かずきのBlog@hatena

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

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>