Visual Studio/WPF > error > エラーCS0535'Person' はインターフェイス メンバー 'INotifyPropertyChanged.PropertyChanged' を実装しません。


Visual Studio 2017 Community (以下VS)
Windows 7 Pro (32bit)

参考: http://www.atmarkit.co.jp/ait/articles/0905/19/news145_3.html

上記のコードを試用する過程において出たエラーについて。

コードとエラー

MainWindow.xaml.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;

//
using System.ComponentModel; 

namespace _170061_t1520_binding_twoway
{
    /// <summary>
    /// MainWindow.xaml の相互作用ロジック
    /// </summary>
    public partial class MainWindow : Window
    {
        public MainWindow()
        {
            InitializeComponent();
        }

        private void MainPanel_Loaded(object sender, RoutedEventArgs e)
        {
            MainPanel.DataContext = new Person();
        }

        private void Button_Click(object sender, RoutedEventArgs e)
        {
            ((Person)MainPanel.DataContext).Calculate();
        }
    }

    class Person : INotifyPropertyChanged
    {
        public double Height { get; set; }
        public double Weight { get; set; }
        public double Bmi { get; private set; }

        public void Calculate()
        {
            Bmi = Weight / Math.Pow(Height, 2);
        }
    }

}

以下のエラーが出た。

重大度レベル コード 説明 プロジェクト ファイル 行 抑制状態
エラー CS0535 'Person' はインターフェイス メンバー 'INotifyPropertyChanged.PropertyChanged' を実装しません。 170061_t1520_binding_twoway c:\users\administrator\documents\visual studio 2017\Projects\170061_t1520_binding_twoway\170061_t1520_binding_twoway\MainWindow.xaml.cs 42 アクティブ

対処

以下をクラスに追加する。

 public event PropertyChangedEventHandler PropertyChanged;

  protected virtual void OnPropertyChanged(string propertyName)
  {
    PropertyChangedEventHandler handler = this.PropertyChanged;
    if (handler != null)
      handler(this, new PropertyChangedEventArgs(propertyName));
  }

全コード

MainWindow.xaml
<Window x:Class="_170061_t1520_binding_twoway.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
        xmlns:local="clr-namespace:_170061_t1520_binding_twoway"
        mc:Ignorable="d"
        Title="MainWindow" Height="350" Width="525">
    <Grid>
        <StackPanel x:Name="MainPanel" Loaded="MainPanel_Loaded">
            <TextBox Margin="10" Text="{Binding Height, Mode=TwoWay}"/>
            <TextBox Margin="10" Text="{Binding Weight, Mode=TwoWay}"/>
            <Button Margin="10" Content="計算" Click="Button_Click"/>
            <TextBlock Margin="10" Text="{Binding Bmi, Mode=OneWay}"/>
        </StackPanel>

    </Grid>
</Window>
MainWindow.xaml.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;

//
using System.ComponentModel; 

namespace _170061_t1520_binding_twoway
{
    /// <summary>
    /// MainWindow.xaml の相互作用ロジック
    /// </summary>
    public partial class MainWindow : Window
    {
        public MainWindow()
        {
            InitializeComponent();
        }

        private void MainPanel_Loaded(object sender, RoutedEventArgs e)
        {
            MainPanel.DataContext = new Person();
        }

        private void Button_Click(object sender, RoutedEventArgs e)
        {
            ((Person)MainPanel.DataContext).Calculate();
        }
    }

    class Person : INotifyPropertyChanged
    {
        double _bmi;

        public double Height { get; set; }
        public double Weight { get; set; }
        public double Bmi
        {
            get { return _bmi; }
            private set
            {
                _bmi = value;
                OnPropertyChanged("Bmi");
            }
        }

        public void Calculate()
        {
            Bmi = Weight / Math.Pow(Height, 2);
        }

        public event PropertyChangedEventHandler PropertyChanged;

        protected virtual void OnPropertyChanged(string propertyName)
        {
            PropertyChangedEventHandler handler = this.PropertyChanged;
            if (handler != null)
                handler(this, new PropertyChangedEventArgs(propertyName));
        }
    }

}

(注意:Personの宣言は上記のような場所に置く事は良くはないだろう。)

エラーメッセージについて

xxxを実装しません

'class' does not implement interface member 'member'

A class derived from an interface, but the class did not implement one or more of the interface's members. A class must implement all members of interfaces from which it derives or else be declared

does notを「実装しません」という訳にしてしまっている。

「xxxが実装されていません。」
もしくは
「xxxを実装してください。」
がIDE利用者にとっては適切なエラーメッセージに思う。

Error Message Guidelines

What can the user do to prevent it from happening again?