2011-07-22 14 views
24

これは、WPF/C#でBindingを使用するための一般的なINotifyPropertyChanged実装です。WPF INotifyPropertyChangedはどのように機能しますか?

namespace notifications.ViewModel 
{ 
    class MainViewModel : INotifyPropertyChanged 
    { 
     public const string NamePropertyName = "CheckBoxState"; 
     private bool _checkboxstate = true; 

     public bool CheckBoxState 
     { 
      get { return _checkboxstate; } 
      set 
      { 
       if (_checkboxstate == value) return; 
       _checkboxstate = value; 
       RaisePropertyChanged(NamePropertyName); 
      } 
     } 
     public event PropertyChangedEventHandler PropertyChanged; 
     private void RaisePropertyChanged(string propertyName) 
     { 
      if (PropertyChanged != null) 
      { 
       PropertyChanged(this, new PropertyChangedEventArgs(propertyName)); 
      } 
     } 
    } 
} 

私もCheckBoxStateに結合したXAMLコードを持っています。 enter image description here

<Grid> 
    <StackPanel HorizontalAlignment="Center" VerticalAlignment="Center"> 
     <CheckBox Content="Click Me" IsChecked="{Binding Path=CheckBoxState, Mode=TwoWay}" /> 
     <TextBlock Text="{Binding Path=CheckBoxState, Mode=TwoWay}" /> 
    </StackPanel> 
</Grid> 

これは、DataContextのとモデルの間でリンクするMainWindow.xaml.csです。ユーザーがチェックボックスを設定すると

public partial class MainWindow : Window 
{ 
    notifications.ViewModel.MainViewModel model = new notifications.ViewModel.MainViewModel(); 

    public MainWindow() 
    { 
     InitializeComponent(); 
     this.DataContext = model; 
    } 
} 

、私は次のように何起こることだと思う:IsCheckedは真となり、そして"{Binding Path=CheckBoxState, Mode=TwoWay}"で、CheckBoxStateプロパティがRaisePropertyChanged()し、それに応じてPropertyChanged()を呼び出すことが真になります。このファンクションのパラメータはCheckBoxStateであるため、パスCheckBoxStateを持つすべてのバインディングは、自身を更新するように通知されます。

  • このコールはどのようにアクティブになりますか<TextBlock Text="{Binding Path=CheckBoxState, Mode=TwoWay}" />?それを可能にするために、この背後にあるC#の魔法は何ですか?
  • なぜif (PropertyChanged != null)が必要ですか? PropertyChangedをどのような値に設定しますか?
  • Mode=TwoWayの意味は、変更を伝えるだけでなく、同じ名前のバインディング要素が変更されたときにコンテンツを更新するように見えます。次に、OneWayモードはどうなりますか?バインディングをソースのみまたはターゲットのみとして設定できますか?

答えて

19

この呼び出しはどのようにアクティブになりますか?これを可能にするために、 の背後にあるC#の魔法は何ですか?

このコードでは、TextBlockのTextプロパティをViewModelプロパティにリンクするBindingオブジェクトを作成します。また、ViewModelがPropertyChangedイベントを(正しいプロパティを使用して)起動するときに、イベントハンドラをViewModelのPropertyChangedイベントに追加してテキスト値を更新します。

なぜif (PropertyChanged != null)が必要ですか? PropertyChangedをどのような値に設定しますか?

PropertyChangedイベントがnullの場合、発生するとNullReferenceExceptionが発生します。

Mode=TwoWayの意味はそれだけではなく 変更に信号を送ることができることのように見えますが、また、コンテンツを更新したときにどのような一方向のモードについて、変更を、結合で 同じ名前を持つ他の結合要素? バインディングをソースまたはターゲットとしてのみ設定できますか?

結合様式は、次のとおり

  • 双方向:一方向のビューモデルのプロパティの変更、結合した値を変更し、その逆
  • は:ときにビューモデルプロパティが変更のみ
  • OneWayToSourceバウンド値を変更します:バインドされた値が変更されたときにViewModelプロパティを変更します
  • OneTime:アプリケーションが作成された直後にViewModelプロパティの値にバインドされた値を設定します。文章の変更。

あなたはここではそれらについての詳細を読むことができます:http://msdn.microsoft.com/en-us/library/system.windows.data.bindingmode.aspx

+1

私は唯一のコントロールが読み込まれるときに、一度更新ワンタイムバインディングモードもあります信じています。 – Yuf

+0

@Yuf:良い点:私はそれを私の答えに加えます。 –

+0

この行はどのように動作しますか?PropertyChanged(this、new PropertyChangedEventArgs(propertyName)); – RSB

関連する問題