簡體   English   中英

x:綁定轉換器和FallbackValue不協作(UWP 10)

[英]x:Bind Converter and FallbackValue not collaborating (UWP 10)

我有一個涉及大量代碼的問題,但我把它隔離了。 如果你想要TL; DR; 進一步向下跳。 如果你想要一點上下文,這是我的情況:

我為我的綁定創建了三個數據轉換器。 其中一個是“字符串前綴”:它為使用固定字符串放入的任何內容添加前綴。 在當前示例中,該固定字符串是"ms-appx:///cache/" 第二個將string類型轉換為ImageSource ,第三個將多個轉換器鏈接在一起。

然后我創建了一個名為LocalCacheFile的Xaml資源。 一切都按照您的想法運作。 Xaml代碼看起來像這樣:

<Image Source="{x:Bind imageSource,Converter={StaticResource LocalCacheFile}}" />

但是,我遇到了以下問題。 如果我嘗試使用FallbackValue為imageSource為空時放置占位符圖像,我會在x:Bind獲得奇怪的行為。

以下代碼可以正常工作

<Image Source="{Binding imageSource,FallbackValue='ms-appx:///Assets/default.png',Converter={StaticResource LocalCacheFile}}" />

<Image Source="{x:Bind imageSource,FallbackValue='ms-appx:///Assets/default.png',Converter={StaticResource LocalCacheFile}}" />

才不是!

我把它分離到只有一個轉換器,它是DependencyProperty.UnsetValue x:Bind似乎沒有處理。

TL; DR; 這是我的字符串前綴的代碼,如果我單獨使用它作為測試觸發相同的錯誤行為:

public class StringPrefix : IValueConverter
{
    public string prefix { get; set; }

    public object Convert(object value, Type typeName, object parameter, string language)
    {
        if (value == DependencyProperty.UnsetValue || value == null || (string)value == "")
            return DependencyProperty.UnsetValue ;

        return (prefix + value.ToString());
    }

    public object ConvertBack(object value, Type typeName, object parameter, string language)
    {
        throw new NotImplementedException();
    }
}

使用Binding時,上述轉換器的工作方式正如您所期望的那樣(即,如果輸入字符串為空,則正確使用了回退值)。 x:Bind一起使用時會引發類型異常。

怎么了?


編輯:有關異常的詳細信息。

這是生成的代碼:

        private void Update_project_imageSource(global::System.String obj, int phase)
        {
            if((phase & ((1 << 0) | NOT_PHASED | DATA_CHANGED)) != 0)
            {
                XamlBindingSetters.Set_Windows_UI_Xaml_Controls_Image_Source(this.obj16, (global::Windows.UI.Xaml.Media.ImageSource)this.LookupConverter("LocalCacheFile").Convert(obj, typeof(global::Windows.UI.Xaml.Media.ImageSource), null, null), null);
            }
        }

例外細節:

System.InvalidCastException was unhandled by user code
  HResult=-2147467262
  Message=Unable to cast object of type 'System.__ComObject' to type 'Windows.UI.Xaml.Media.ImageSource'.
  Source=Test
  StackTrace:
       at Test.Pages.ProjectView.ProjectView_obj1_Bindings.Update_project_imageSource(String obj, Int32 phase)
       at Test.Pages.ProjectView.ProjectView_obj1_Bindings.Update_project(Project obj, Int32 phase)
       at Test.Pages.ProjectView.ProjectView_obj1_Bindings.Update_(ProjectView obj, Int32 phase)
       at Test.Pages.ProjectView.ProjectView_obj1_Bindings.Update()
       at Test.Pages.ProjectView.<.ctor>b__6_0(FrameworkElement s, DataContextChangedEventArgs e)
  InnerException: 

(對我來說,看起來生成的代碼只是不處理默認值的可能性。順便說一下, __ComObjectDependencyProperty.UnsetValue

編輯2 :我應該補充一點,如果我將Convert函數更改為返回null而不是DependencyProperty.UnsetValue, x:Bind函數,但是x:BindBinding都沒有執行使用FallbackValue的預期工作

BindingFallbackValuex:Bind是不同的。

BindingFallbackValue是綁定無法返回值時使用的值。

對於Path根本不對數據源進行求值的情況,或者如果嘗試使用雙向綁定在源上設置它,則綁定使用FallbackValue會拋出數據綁定引擎捕獲的異常。 如果源值是依賴項屬性sentinel值DependencyProperty.UnsetValue,則還使用FallbackValue

但是在x:BindFallbackValue指定在無法解析源或路徑時顯示的值。 它無法與DependencyProperty.UnsetValue

正如您已經知道的那樣, x:Bind在編譯時生成代碼並且它是強類型的。 當您在x:Bind使用Converter時,它會將Converter的返回值視為與target屬性相同的類型,並將其Converter為您的代碼:

(global::Windows.UI.Xaml.Media.ImageSource)this.LookupConverter("LocalCacheFile").Convert(obj, typeof(global::Windows.UI.Xaml.Media.ImageSource), null, null)

如果在Converter返回DependencyProperty.UnsetValue ,它將拋出異常,因為DependencyProperty.UnsetValue無法ImageSource ConverterImageSource

對於您的方案,您可以使用TargetNullValue

TargetNullValue是一個類似的屬性,具有類似的場景。 不同之處在於,如果Path和Source進行求值,則綁定使用TargetNullValue ,但在此處找到的值為null。

例如,使用以下代碼是XAML。

<Image Source="{x:Bind imageSource, TargetNullValue='ms-appx:///Assets/default.png', Converter={StaticResource LocalCacheFile}}" />

Convert ,返回null而不是DependencyProperty.UnsetValue

這在運行應用程序並且imageSource為空時有效。 但為了獲得設計時間的好處,我們仍然需要使用FallbackValue 所以我們可以使用x:Bind如下:

<Image Source="{x:Bind imageSource, TargetNullValue='ms-appx:///Assets/default.png', FallbackValue='ms-appx:///Assets/default.png', Converter={StaticResource LocalCacheFile}}" />

x:Bind FallBackValue實際上僅用於設計時數據。 現在,讓我們談談更重要的事情。 為什么使用x:Bind 通過調整IValueConverter的成本,您是否確信x:Bind值得嗎? 我不是。 當我看到開發人員努力獲得x:Bind工作正確綁定列表的OUTSIDE時,我的建議是切換到binding 每次。 在列表中,編譯的綁定具有“重復”值,但在其他任何地方,你必須向我證明它是值得的 - 如果它是困難的話。 通常x:bind很棒。 但是在這種情況下,像UpdateSourceTrigger這樣的情況會回落或默認為binding完全正常。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM