かずきのBlog@hatena

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

UWPのコンパイル時データバインディング(x:BInd)でPropertyChanged_XXXXXがないというコンパイルエラーが出るとき

UWPのコンパイル時データバインディングを試してたのですが、こんなコードを書いたら表題のようなコンパイルエラーが出るようになりました。

public sealed partial class MainPage : Page
{
    public MainPage()
    {
        this.InitializeComponent();
    }
}

class MainPageVM : INotifyPropertyChanged
{
    public string Text { get; set; } = "Hello world";

    public event PropertyChangedEventHandler PropertyChanged;
}
<Page
    x:Class="App43.MainPage"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:local="using:App43"
    xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
    xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
    mc:Ignorable="d">
    <Page.DataContext>
        <local:MainPageVM x:Name="ViewModel" />
    </Page.DataContext>
    <Grid Background="{ThemeResource ApplicationPageBackgroundThemeBrush}">
        <TextBlock Text="{x:Bind ViewModel.Text, Mode=OneWay}" />
    </Grid>
</Page>

すると

現在のコンテキストに 'PropertyChanged_ViewModel' という名前は存在しません。

というエラーが出ます。

条件

ViewModelがINotifyPropertyChangedを実装していて、XAMLでx:Nameを使って変数宣言していて、Mode=OneTime以外を指定すると起きるっぽいです。

解決策

プロパティ化するなりフィールド化するなりしましょう。

public sealed partial class MainPage : Page
{
    private MainPageVM ViewModel => this.DataContext as MainPageVM;
    public MainPage()
    {
        this.InitializeComponent();
    }
}

class MainPageVM : INotifyPropertyChanged
{
    public string Text { get; set; } = "Hello world";

    public event PropertyChangedEventHandler PropertyChanged;
}
<Page
    x:Class="App43.MainPage"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:local="using:App43"
    xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
    xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
    mc:Ignorable="d">
    <Page.DataContext>
        <local:MainPageVM />
    </Page.DataContext>
    <Grid Background="{ThemeResource ApplicationPageBackgroundThemeBrush}">
        <TextBlock Text="{x:Bind ViewModel.Text, Mode=OneWay}" />
    </Grid>
</Page>