15

In XAML I have the following line:

<Image x:Name="MainImage" 
       Source="{x:Bind ViewModel.MainPic,Mode=OneWay,TargetNullValue={x:Null}}"
       Stretch="UniformToFill"/>

In ViewModel:

public string MainPic
{
    get
    {
        if (Data == null)
            return default(string);
        else
            return Data.Photos.ElementAtOrDefault(0).url;
    }
}

App compiles fine but during execution (since Data is populated after few seconds), the app crashes with the following exception:

System.ArgumentException: The parameter is incorrect.

Debugger breaks at:

            private void Update_ViewModel_MainPic(global::System.String obj, int phase)
            {
                if((phase & ((1 << 0) | NOT_PHASED | DATA_CHANGED)) != 0)
                {
 /*HERE>>*/          XamlBindingSetters.Set_Windows_UI_Xaml_Controls_Image_Source(this.obj23, (global::Windows.UI.Xaml.Media.ImageSource) global::Windows.UI.Xaml.Markup.XamlBindingHelper.ConvertValue(typeof(global::Windows.UI.Xaml.Media.ImageSource), obj), null);
                }
            }

Apparently, this occurs since MainPic is returning null.

Now, this code works fine in WP8.1. I have tried returning uri which results in Compile time error. I believe only string can be binded to image source in Win 10 (?) I just want a blank white area until data is populated hence I don't wish to give a local image source as fallback. Can someone help me port this for Win 10?


UPDATE:

Thanks to the users who answered, following conclusion is drawn (for UWP):

  • If you're binding image source to a string, it cannot be null or empty "". A singe character "x" or a space " " would work.
  • If you bind to a BitmapImage, returning null works.
  • You can use any of the methods mentioned by @Justin-xl . For me, changing all vm's to stop returning null was hard. So adding a simple convertor to xaml also does the trick.

Here's the converter code:

public object Convert(object value, Type targetType, object parameter, string language)
{
    if (string.IsNullOrEmpty(value as string))
    {
        return null;
    }
    else return new BitmapImage(new Uri(value as string, UriKind.Absolute));
}
4

1 回答 1

15

如果使用x:Bind,需要绑定到完全相同类型的属性Source(例如)而不是,否则会抛出编译时错误,这正是编译时绑定应该做的。旧绑定允许使用字符串,因为它使用反射在运行时为您解析类型。ImageImageSourceBitmapImagestring

原来我的明确类型理论是错误的(感谢@igrali 指出)。Source确实需要 astring只要它不是nullor ''。所以它给我们留下了两个选择来解决这个问题。

选项1

保留你的urias string,但检查你的vm,一旦它是nullor '',返回一些虚拟文本(即使返回一封信x也可以!)。

选项 2

uri将字符串从字符串更改为BitmapImage。然后您可以使用TargetNullValueandFallbackValue来处理空值和无效绑定。

... FallbackValue='http://Assets/SplashScreen.png' TargetNullValue='http://Assets/SplashScreen.png'}"
于 2015-08-08T23:26:02.873 回答