我有一个问题,涉及到一堆代码,但我已经把它隔离了下来。如果你想要一个TL,请跳到更低的地方。如果你想了解一些情况,下面是我的情况:
我已经为我的绑定创建了三个数据转换器。其中之一是“字符串前缀器”:它用一个固定的字符串作为前缀。在当前示例中,该固定字符串为"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}}" />不会的!
我只将它隔离为一个转换器,而x:Bind似乎没有处理这个DependencyProperty.UnsetValue。
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: (在我看来,生成的代码似乎没有处理默认值的可能性。顺便说一句,__ComObject就是DependencyProperty.UnsetValue。
编辑2:如果我将转换函数更改为返回null而不是DependencyProperty.UnsetValue、x:Bind函数,那么x:Bind和Binding都不会完成使用FallbackValue的预期任务。
发布于 2016-02-05 07:42:15
FallbackValue在Binding和x:Bind中是不同的。
在Binding中,当绑定无法返回值时,FallbackValue是要使用的值。
绑定使用FallbackValue来处理以下情况:路径根本不对数据源进行计算,或者如果试图通过双向绑定将其设置在数据源上,则会引发数据绑定引擎捕获的异常。如果源值是依赖项属性sentinel值DependencyProperty.UnsetValue,则还使用DependencyProperty.UnsetValue。
但是在x:Bind中,当源或路径无法解析时,FallbackValue指定要显示的值。它不能与DependencyProperty.UnsetValue一起工作。
正如您已经知道的,x:Bind在编译时生成代码,并且它是强类型的。在Converter中使用x:Bind时,它将把相同类型的Converter的返回值视为目标属性,并在代码中进行如下转换:
(global::Windows.UI.Xaml.Media.ImageSource)this.LookupConverter("LocalCacheFile").Convert(obj, typeof(global::Windows.UI.Xaml.Media.ImageSource), null, null)如果在您的DependencyProperty.UnsetValue中返回Converter,它将抛出异常,因为DependencyProperty.UnsetValue不能转换为ImageSource。
对于您的场景,您可以使用TargetNullValue。
TargetNullValue是一个类似的属性,具有类似的场景。不同之处在于,如果路径和源确实计算,但是找到的值为null,则绑定使用TargetNullValue。
例如,使用以下代码是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}}" />发布于 2016-02-07 06:17:20
在x:Bind中,FallBackValue实际上只用于设计时数据。现在,让我们谈谈更重要的事情。为什么要使用x:Bind。考虑到制作IValueConverter的成本,您认为x:Bind值得吗?我没有。当我看到开发人员很难让x:Bind在列表之外的绑定中正确工作时,我的建议是切换到binding。每次都是这样。在列表中,编译后的绑定有一个“重复”值,但是在任何其他地方,您都必须向我证明它是值得的--如果不是这样很困难的话。典型的x:bind是很棒的。但是,在这种情况下,以及像UpdateSourceTrigger回到或默认为binding的情况都是很好的。
https://stackoverflow.com/questions/35200838
复制相似问题