MB.*_*MB. 4 c# winrt-xaml winrt-xaml-toolkit uwp
我有一个涉及大量代码的问题,但我把它隔离了.如果你想要TL; DR; 进一步向下跳.如果你想要一点上下文,这是我的情况:
我为我的绑定创建了三个数据转换器.其中一个是"字符串前缀":它为使用固定字符串放入的任何内容添加前缀.在当前示例中,该固定字符串是"ms-appx:///cache/".第二个将string类型转换为a ImageSource,第三个将多个转换器链接在一起.
然后我创建了一个名为Xaml的资源LocalCacheFile.一切都按照您的想法运作.Xaml代码看起来像这样:
<Image Source="{x:Bind imageSource,Converter={StaticResource LocalCacheFile}}" />
Run Code Online (Sandbox Code Playgroud)
但是,我遇到了以下问题.如果我尝试使用FallbackValue为占位符图像设置imageSource为空时,我x:Bind只会出现奇怪的行为.
以下代码可以正常工作:
<Image Source="{Binding imageSource,FallbackValue='ms-appx:///Assets/default.png',Converter={StaticResource LocalCacheFile}}" />
Run Code Online (Sandbox Code Playgroud)
但
<Image Source="{x:Bind imageSource,FallbackValue='ms-appx:///Assets/default.png',Converter={StaticResource LocalCacheFile}}" />
Run Code Online (Sandbox Code Playgroud)
才不是!
我把它分离到只有一个转换器,它是DependencyProperty.UnsetValuex: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();
}
}
Run Code Online (Sandbox Code Playgroud)
使用时,上述转换器的工作方式与您预期的一样(即,如果输入字符串为空,则回退值已正确使用)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);
}
}
Run Code Online (Sandbox Code Playgroud)
例外细节:
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:
Run Code Online (Sandbox Code Playgroud)
(对我来说,看起来生成的代码只是不处理默认值的可能性.顺便说一下,__ComObject就是这样DependencyProperty.UnsetValue.
编辑2:我应该补充一点,如果我将Convert函数更改为返回null而不是DependencyProperty.UnsetValue,则x:Bind函数,但后来既没有x:Bind也没有Binding做他们预期的使用FallbackValue
该FallbackValue中Binding和x:Bind是不同的.
In Binding,FallbackValue是绑定无法返回值时使用的值.
对于Path根本不对数据源进行求值的情况,或者如果尝试使用双向绑定在源上设置它,则绑定使用FallbackValue会抛出数据绑定引擎捕获的异常.如果源值是依赖属性Sentinel值DependencyProperty.UnsetValue,则还使用FallbackValue.
但是x:Bind,FallbackValue指定在无法解析源或路径时显示的值.它无法使用DependencyProperty.UnsetValue.
正如您所知,x:Bind在编译时生成代码并且它是强类型的.当你使用Converterin时x:Bind,它会将Converter与类型相同类型的返回值视为目标属性,并将其转换为代码:
(global::Windows.UI.Xaml.Media.ImageSource)this.LookupConverter("LocalCacheFile").Convert(obj, typeof(global::Windows.UI.Xaml.Media.ImageSource), null, null)
Run Code Online (Sandbox Code Playgroud)
如果你返回DependencyProperty.UnsetValue,你Converter将抛出异常,因为DependencyProperty.UnsetValue无法施放ImageSource.
对于您的方案,您可以使用TargetNullValue.
TargetNullValue是一个类似的属性,具有类似的场景.不同之处在于,如果Path和Source进行求值,则绑定使用TargetNullValue,但在此处找到的值为null.
例如,使用以下代码是XAML.
<Image Source="{x:Bind imageSource, TargetNullValue='ms-appx:///Assets/default.png', Converter={StaticResource LocalCacheFile}}" />
Run Code Online (Sandbox Code Playgroud)
而在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}}" />
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
2594 次 |
| 最近记录: |