[Silverlight][バインディング] クラスのインスタンスをバインドする3 ~データを更新する~

前回と前々回の記事で、クラスのインスタンスをバインドする方法について説明しました。
前回および前々回は、インスタンスにセットされたデータを表示するだけでしたが、今回はインスタンスのデータを変更し表示に反映されるようにしてみます。
また、今回使用する技術は INotifyPropertyChagedインターフェースです。

まずは、前々回の記事を参照して Silverlightアプリケーションプロジェクトを作成します。
次に MainPage.xaml に以下のようにボタンを追加します。

MainPage.xamlのデザイン
Buttonコントロールの Contentプロパティは「変更」にしておきます。

次に、貼り付けた Button コントロールをダブルクリックして以下のコードを入力します。

VB.NET

Partial Public Class MainPage
    Inherits UserControl

    Private _health As New Health()


    Public Sub New()
        InitializeComponent()

        _health.Height = 162.5
        _health.Weight = 60.5

        Me.DataContext = _health
    End Sub

    ''' <summary>
    ''' ボタンクリック時の処理
    ''' </summary>
    ''' <param name="sender"></param>
    ''' <param name="e"></param>
    ''' <remarks></remarks>
    Private Sub Button_Click(sender As Object, e As RoutedEventArgs)
        _health.Height = 170.5
        _health.Weight = 55.5
    End Sub
End Class

C#

public partial class MainPage : UserControl
{
    private Health _health;

    public MainPage()
    {
        InitializeComponent();

        _health = new Health
        {
            Height = 162.5,
            Weight = 60.5
        };

        this.DataContext = _health;
    }

    /// <summary>
    /// ボタンクリック時の処理
    /// </summary>
    /// <param name="sender"></param>
    /// <param name="e"></param>
    private void Button_Click(object sender, System.Windows.RoutedEventArgs e)
    {
        _health.Height = 170.5;
        _health.Weight = 55.5;
    }
}

上記を入力したら、実行してみましょう。
あれ?ボタンをクリックしても画面に表示されている値が更新されません。
データが更新されないのは、MainPageに表示されている TextBlockコントロールが フィールドの値が変更をされていることを知らないためです。
この問題を解決するには、Healthクラスに INotifyPropertyChangedインターフェースを実装する必要があります。
以下に INotyfyPropertyChangedインターフェースを実装した Healthクラスのコードを示します。

VB.NET

'INotifyPropertyChangedを実装するために以下を追記します
Imports System.ComponentModel

Public Class Health
    Implements INotifyPropertyChanged

    Private _height As Double
    Private _weight As Double

    ''' <summary>
    ''' 身長用プロパティ
    ''' </summary>
    ''' <value></value>
    ''' <returns></returns>
    ''' <remarks></remarks>
    Public Property Height() As Double
        Get
            Return _height
        End Get
        Set(ByVal value As Double)
            _height = value

            'Heightプロパティを変更した時に、PropertyChangedイベントをキックします
            NotifyPropertyChanged("Height")
        End Set
    End Property

    ''' <summary>
    ''' 体重用プロパティ
    ''' </summary>
    ''' <value></value>
    ''' <returns></returns>
    ''' <remarks></remarks>
    Public Property Weight() As Double
        Get
            Return _weight
        End Get
        Set(ByVal value As Double)
            _weight = value

            'Weightプロパティを変更した時に、PropertyChangedイベントをキックします
            NotifyPropertyChanged("Weight")
        End Set
    End Property

    '以下のイベントを追加
    Public Event PropertyChanged(sender As Object, e As PropertyChangedEventArgs) Implements INotifyPropertyChanged.PropertyChanged

    ''' <summary>
    ''' 上記のイベントをキックするために、下記のNotifyPropertyChangedメソッドを追加
    ''' </summary>
    ''' <param name="p"></param>
    ''' <remarks></remarks>
    Private Sub NotifyPropertyChanged(p As String)
        RaiseEvent PropertyChanged(Me, New PropertyChangedEventArgs(p))
    End Sub

End Class

C#

// INotifyPropertyChangedを実装するために以下を追記します
using System.ComponentModel;

namespace SilverlightApplication1
{
    public class Health : INotifyPropertyChanged
    {
        private double _height;

        private double _weight;

        /// <summary>
        /// 身長用プロパティ
        /// </summary>
        public double Height 
        { 
            get
            {
                return _height;
            }
            set
            {
                _height = value;

                // Heightプロパティを変更した時に、PropertyChangedイベントをキックします
                NotifyPropertyChanged("Height");
            }
        }

        /// <summary>
        /// 体重用プロパティ
        /// </summary>
        public double Weight 
        { 
            get
            {
                return _weight;
            }
            set
            {
                _weight = value;

                // Weightプロパティを変更した時に、PropertyChangedイベントをキックします
                NotifyPropertyChanged("Weight");
            }
        }

        // 以下のイベントを追加
        public event PropertyChangedEventHandler PropertyChanged;

        /// <summary>
        /// 上記のイベントをキックするために、下記のNotifyPropertyChangedメソッドを追加
        /// </summary>
        /// <param name="p"></param>
        private void NotifyPropertyChanged(string p)
        {
            if (PropertyChanged  != null)
            {
                PropertyChanged(this, new PropertyChangedEventArgs(p));
            }
        }
    }
}

INotyfyPropertyChangedインターフェースを実装する場合は以下に注意しましょう。

  • プロパティ値を変更したら(プロパティのSet部) NotifyPropertyChangedを呼ぶ
  • PropertyChangedEventHandlerを追加する

コードの入力が終わったら、実行して[変更]ボタンをクリックしてみましょう。
以下のように、表示値が変更されることを確認してください。
実行結果

コメントを残す

メールアドレスが公開されることはありません。 * が付いている欄は必須項目です

このサイトはスパムを低減するために Akismet を使っています。コメントデータの処理方法の詳細はこちらをご覧ください