読者です 読者をやめる 読者になる 読者になる

かずきのBlog@hatena

日本マイクロソフトに勤めています。XAML + C#の組み合わせをメインに、たまにASP.NETやJavaなどの.NET系以外のことも書いています。掲載内容は個人の見解であり、所属する企業を代表するものではありません。

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が入らないように制御するか。