C# x:绑定转换器和回退值不协作(UWP 10)
我有一个问题,涉及到一堆代码,但我已经把它隔离了。如果你想要一个TL;博士再往下跳。如果你想了解一些情况,以下是我的情况: 我已经为绑定创建了三个数据转换器。其中一个是“字符串前缀器”:它以固定字符串作为输入内容的前缀。在当前示例中,该固定字符串为C# x:绑定转换器和回退值不协作(UWP 10),c#,winrt-xaml,uwp,winrt-xaml-toolkit,C#,Winrt Xaml,Uwp,Winrt Xaml Toolkit,我有一个问题,涉及到一堆代码,但我已经把它隔离了。如果你想要一个TL;博士再往下跳。如果你想了解一些情况,以下是我的情况: 我已经为绑定创建了三个数据转换器。其中一个是“字符串前缀器”:它以固定字符串作为输入内容的前缀。在当前示例中,该固定字符串为“ms-appx:///cache/“。第二个将字符串类型转换为图像源,第三个将多个转换器链接在一起 然后我创建了一个称为LocalCacheFile的Xaml资源。一切都按照你的想法进行。这方面的Xaml代码如下所示: <Image Sourc
“ms-appx:///cache/“
。第二个将字符串
类型转换为图像源
,第三个将多个转换器链接在一起
然后我创建了一个称为LocalCacheFile
的Xaml资源。一切都按照你的想法进行。这方面的Xaml代码如下所示:
<Image Source="{x:Bind imageSource,Converter={StaticResource LocalCacheFile}}" />
但是
使用绑定时,上述转换器的工作方式与您预期的相同(即,如果输入字符串为空,则正确使用回退值)。与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);
}
}
private void Update\u project\u imageSource(全局::System.String obj,int阶段)
{
如果((阶段)和((1在Binding
和x:Bind
中的FallbackValue
不同
在绑定中
,是绑定无法返回值时要使用的值
绑定使用FallbackValue用于根本不对数据源求值的情况,或者如果试图使用双向绑定在源上设置它,会引发数据绑定引擎捕获的异常。如果源值是依赖属性sentinel值,也会使用FallbackValue
但是在x:Bind
中,指定了当源或路径无法解析时要显示的值。它不能使用DependencyProperty.UnsetValue
正如您已经知道的,x:Bind
在编译时生成代码,并且它是强类型的。当您在x:Bind
中使用Converter
时,它会将类型相同的Converter
返回值视为目标属性,并在代码中强制转换它:
(global::Windows.UI.Xaml.Media.ImageSource)this.LookupConverter("LocalCacheFile").Convert(obj, typeof(global::Windows.UI.Xaml.Media.ImageSource), null, null)
如果在转换器中返回dependencProperty.UnsetValue
,它将抛出异常作为dependencProperty.UnsetValue
无法转换到ImageSource
对于您的场景,可以使用TargetNullValue
TargetNullValue是一个具有类似场景的类似属性。不同之处在于,如果路径和源确实求值,但在那里找到的值为null,则绑定使用TargetNullValue
例如,使用以下代码的是XAML
<Image Source="{x:Bind imageSource, TargetNullValue='ms-appx:///Assets/default.png', Converter={StaticResource LocalCacheFile}}" />
在x:Bind
中,FallBackValue
实际上只用于设计时数据。现在,让我们来谈谈更重要的事情。为什么要使用x:Bind
。以开发IValueConverter
的成本为代价,你确信x:Bind
值得吗?我不相信。当我看到开发人员努力获得x:Bind>时
要正确处理列表外的绑定,我的建议是切换到绑定
。每次。在列表内,编译的绑定有一个“重复”值,但在其他任何地方,您都必须向我证明,这是值得努力的-如果这是其他困难的话。通常x:bind
非常好。但是在这样的情况下,以及UpdateSourceTrigger
这样的情况下,返回到绑定或默认为绑定是非常好的。您能添加关于typexe>的详细信息吗Option
?我添加了异常信息。不是作为解决方案,而是作为解决方法:使用参数
提供回退值,而不是绑定本身的实际回退值如何?是的,我也尝试过。回退值有两个优点:运行时和设计时优势。最后,我刚刚ted对运行时解决方案进行了胡乱的研究(即通过复制占位符图像),特别是考虑到我没有预见到数据模型的任何缩放问题。也就是说,我认为这是一个真正的错误。x:Bind的另一个烦恼(我必须链接转换器的原因):转换后,类型强制将丢失。您可以绑定到数据为字符串类型的源属性,但如果转换器输出字符串,则无法绑定。这很烦人。我同意这是一个错误。但我有点好奇,为什么会有COM_对象…请确保向报告此错误!如果在那里创建了任何响应,请确保向上报告请注明此问题的日期。谢谢,此解决方案非常好!我不知道它是如何发生的,但我直到一年后才看到它。我已将其标记为已解决,很抱歉延迟!这是一个很好的示例,说明了为什么在UWP中,我们不从转换器返回未设置值!
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:
(global::Windows.UI.Xaml.Media.ImageSource)this.LookupConverter("LocalCacheFile").Convert(obj, typeof(global::Windows.UI.Xaml.Media.ImageSource), null, null)
<Image Source="{x:Bind imageSource, TargetNullValue='ms-appx:///Assets/default.png', Converter={StaticResource LocalCacheFile}}" />
<Image Source="{x:Bind imageSource, TargetNullValue='ms-appx:///Assets/default.png', FallbackValue='ms-appx:///Assets/default.png', Converter={StaticResource LocalCacheFile}}" />