首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >x:Bind转换器与FallbackValue不合作(UWP 10)

x:Bind转换器与FallbackValue不合作(UWP 10)
EN

Stack Overflow用户
提问于 2016-02-04 12:18:10
回答 2查看 3.5K关注 0票数 7

我有一个问题,涉及到一堆代码,但我已经把它隔离了下来。如果你想要一个TL,请跳到更低的地方。如果你想了解一些情况,下面是我的情况:

我已经为我的绑定创建了三个数据转换器。其中之一是“字符串前缀器”:它用一个固定的字符串作为前缀。在当前示例中,该固定字符串为"ms-appx:///cache/"。第二种方法将string类型转换为ImageSource,第三种类型将多个转换器连接在一起。

然后,我创建了一个名为LocalCacheFile的Xaml资源。一切都像你想的那样运作。用于此的Xaml代码如下所示:

代码语言:javascript
复制
<Image Source="{x:Bind imageSource,Converter={StaticResource LocalCacheFile}}" />

但是,我有以下问题。如果我尝试使用FallbackValue来为imageSource为空时放置占位符图像,我只会在x:Bind中得到奇怪的行为。

下面的代码如人们所期望的那样工作

代码语言:javascript
复制
<Image Source="{Binding imageSource,FallbackValue='ms-appx:///Assets/default.png',Converter={StaticResource LocalCacheFile}}" />

代码语言:javascript
复制
<Image Source="{x:Bind imageSource,FallbackValue='ms-appx:///Assets/default.png',Converter={StaticResource LocalCacheFile}}" />

不会的!

我只将它隔离为一个转换器,而x:Bind似乎没有处理这个DependencyProperty.UnsetValue

TL;DR;这里是我的字符串前缀程序的代码,如果我单独用作测试,它会触发相同的错误行为:

代码语言:javascript
复制
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一起使用时,它会引发类型异常。

这怎么回事?

编辑:关于异常的详细信息。

这是生成的代码:

代码语言:javascript
复制
        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);
            }
        }

例外细节:

代码语言:javascript
复制
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:BindBinding都不会完成使用FallbackValue的预期任务。

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2016-02-05 07:42:15

FallbackValueBindingx:Bind中是不同的。

Binding中,当绑定无法返回值时,FallbackValue是要使用的值。

绑定使用FallbackValue来处理以下情况:路径根本不对数据源进行计算,或者如果试图通过双向绑定将其设置在数据源上,则会引发数据绑定引擎捕获的异常。如果源值是依赖项属性sentinel值DependencyProperty.UnsetValue,则还使用DependencyProperty.UnsetValue

但是在x:Bind中,当源或路径无法解析时,FallbackValue指定要显示的值。它不能与DependencyProperty.UnsetValue一起工作。

正如您已经知道的,x:Bind在编译时生成代码,并且它是强类型的。在Converter中使用x:Bind时,它将把相同类型的Converter的返回值视为目标属性,并在代码中进行如下转换:

代码语言:javascript
复制
(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。

代码语言:javascript
复制
<Image Source="{x:Bind imageSource, TargetNullValue='ms-appx:///Assets/default.png', Converter={StaticResource LocalCacheFile}}" />

Convert中,返回null而不是DependencyProperty.UnsetValue

这在运行应用程序和imageSource是空的时候起作用。但是为了获得设计时间的效益,我们仍然需要使用FallbackValue。因此,我们可以使用x:Bind,如下所示:

代码语言:javascript
复制
<Image Source="{x:Bind imageSource, TargetNullValue='ms-appx:///Assets/default.png', FallbackValue='ms-appx:///Assets/default.png', Converter={StaticResource LocalCacheFile}}" />
票数 8
EN

Stack Overflow用户

发布于 2016-02-07 06:17:20

x:Bind中,FallBackValue实际上只用于设计时数据。现在,让我们谈谈更重要的事情。为什么要使用x:Bind。考虑到制作IValueConverter的成本,您认为x:Bind值得吗?我没有。当我看到开发人员很难让x:Bind在列表之外的绑定中正确工作时,我的建议是切换到binding。每次都是这样。在列表中,编译后的绑定有一个“重复”值,但是在任何其他地方,您都必须向我证明它是值得的--如果不是这样很困难的话。典型的x:bind是很棒的。但是,在这种情况下,以及像UpdateSourceTrigger回到或默认为binding的情况都是很好的。

票数 4
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/35200838

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档