かずきのBlog@hatena

すきな言語は C# + XAML の組み合わせ。Azure Functions も好き。最近は Go 言語勉強中。日本マイクロソフトで働いていますが、ここに書いていることは個人的なメモなので会社の公式見解ではありません。

UWPのImageのSourceにnullや空文字をx:Bindしたときの対処方法(対処できない)

UWP の x:Bind で ImageSource を指定すると null や string.Empty のときにエラーが発生する | 雪猫ノート

間にConverterが入るケースだとnullとか渡すとエラーになっちゃうんですよね…そのままnull返してくれればいいものを。 ということで、ViewModel側でImageSourceを持つようにしないといけないです。

using System;
using Windows.UI.Xaml.Controls;
using Windows.UI.Xaml.Media;
using Windows.UI.Xaml.Media.Imaging;

namespace App47
{
    public sealed partial class MainPage : Page
    {
        private MainPageViewModel ViewModel { get; } = new MainPageViewModel();

        public MainPage()
        {
            this.InitializeComponent();
        }
    }

    class MainPageViewModel
    {
        public ImageSource NullImage { get; set; }
    }
}

こんな感じのVMを定義しておいて、以下のようなXAMLを定義すると型変換が入らないのでエラーが出なくなります。解せぬ動きですね…。

<Page x:Class="App47.MainPage"
      xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
      xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
      xmlns:local="using:App47"
      xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
      xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
      mc:Ignorable="d">

    <Grid Background="{ThemeResource ApplicationPageBackgroundThemeBrush}">
        <Image Source="{x:Bind ViewModel.NullImage}" />
    </Grid>
</Page>

ちなみにnullのときに表示したい値はTargetNullValueで設定できます。こんな感じに

<Page x:Class="App47.MainPage"
      xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
      xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
      xmlns:local="using:App47"
      xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
      xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
      mc:Ignorable="d">

    <Grid Background="{ThemeResource ApplicationPageBackgroundThemeBrush}">
        <Image Source="{x:Bind ViewModel.NullImage, TargetNullValue=ms-appx:///Assets/StoreLogo.png}" />
    </Grid>
</Page>

とここで思いついたのですが

FallbackValueというプロパティがx:Bindにあるのを思い出しました。

結論からいうとこれを指定してもダメでした。自動生成されたソースを読むとPageやViewModelがnullのときに使用されるらしい…。今回の用途向けじゃないのね…。

まとめ

VとVMで型を合わせておくのが無難っぽいです。もしくは、nullが入らないように制御するか。