2011-06-18 19 views
3

wpfでデータバインディングを使用していて問題が発生しました。ここに私のコードは次のとおりです。WPFのクラスとサブクラスによるDataContextへのバインド

MainWindow.xaml

<Window x:Class="TestWpf.MainWindow" 
     xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
     xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
     xmlns:local="clr-namespace:TestWpf" 
     Title="MainWindow" Height="350" Width="525">  
    <StackPanel Name="stackpanel"> 
     <TextBox Name="tb1" Text="{Binding Path=A.Number}" /> 
     <TextBox Name="tb2" Text="{Binding Path=B.Number}" /> 
     <TextBlock Name="tbResult" Text="{Binding Path=C}" /> 
    </StackPanel> 
</Window> 

MainWindow.xaml.cs

public partial class MainWindow : Window 
{ 
    public MainWindow() 
    { 
     InitializeComponent(); 
     MyClass myClass = new MyClass(); 
     myClass.A = new MySubClass(); 
     myClass.B = new MySubClass(); 
     stackpanel.DataContext = myClass; 
    } 
} 

MyClass.cs

class MyClass : INotifyPropertyChanged 
{ 
    private MySubClass a; 
    public MySubClass A 
    { 
     get { return a; } 
     set 
     { 
      a = value; 
      OnPropertyChanged("A"); 
      OnPropertyChanged("C"); 
     } 
    } 

    private MySubClass b; 
    public MySubClass B 
    { 
     get { return b; } 
     set 
     { 
      b = value; 
      OnPropertyChanged("B"); 
      OnPropertyChanged("C"); 
     } 
    } 

    public int C 
    { 
     get { return A.Number + B.Number; } 
    } 

    public event PropertyChangedEventHandler PropertyChanged; 
    private void OnPropertyChanged(string p) 
    { 
     if (PropertyChanged != null) 
     { 
      PropertyChanged(this, new PropertyChangedEventArgs(p)); 
     } 
    }   
} 

MySubClass.cs

class MySubClass : INotifyPropertyChanged 
{ 
    private int number; 
    public int Number 
    { 
     get { return number; } 
     set 
     { 
      number = value; 
      OnPropertyChanged("Number"); 
     } 
    } 

    public MySubClass() 
    { 
     Number = 1; 
    } 

    public event PropertyChangedEventHandler PropertyChanged; 
    private void OnPropertyChanged(string p) 
    { 
     if (PropertyChanged != null) 
     { 
      PropertyChanged(this, new PropertyChangedEventArgs(p)); 
     } 
    }  
} 

、問題は、私はアプリを実行した後に結合が、正常に動作していることです。また、A.NumberとB.Numberの値は、テキストボックスで値を変更すると更新されます。しかし、MyClass.Cの変数Cは、アプリの起動時と終了後にのみ更新されます。 A.NumberまたはB.Numberを変更すると、Cが更新されるように変更する必要があります。ありがとう。

答えて

3

データモデルを更新するときに、MySubClassインスタンスのNumberを直接変更するか、新しいサブクラスをMyClassインスタンスに割り当てますか?すなわち:

myClass.A.Number = 5; // will trigger OnPropertyChanged on MySubClass, but not on MyClass 

は、AでOnPropertyChangedをトリガーしません(もちろんA.Numberを更新します)。

MySubClass v = new MySubClass() 
v.Number = 5; 
myClass.A = v; // will trigger OnPropertyChanged on MyClass 

更新答:あなたのような何かをする必要があり、この作業では 。あなたはaとbのプロパティの変更をキャッチするためにこれを行うことができます。

public MyClass() 
{ 
    a.PropertyChanged += new PropertyChangedEventHandler(UpdateC); 
    b.PropertyChanged += new PropertyChangedEventHandler(UpdateC); 
} 

void UpdateC(object sender, PropertyChangedEventArgs e) 
{ 
    OnPropertyChanged("C"); 
} 
+0

答えてくれてありがとうございますが、何とかMySubClassをインスタンス化せずにプロパティCを更新することは可能です – Marin

1
A.NumberまたはB.Numberを変更するとCが更新されるように変更する必要があります。

AプロパティとBプロパティの変更をリッスンする必要があります。このコードをAセッターに追加するとうまくいくはずです:



set 
{ 
if (a != null) 
{ 
a.PropertyChanged-=NumberChanged; 
} 
a = value; 
a.PropertyChanged+=NumberChanged; 
OnPropertyChanged("A"); 
OnPropertyChanged("C"); 
} 

private void NumberChanged(object sender, PropertyChangedEventArgs e) 
{ 
    if (e.PropertyName == "Number") 
    { 
    OnPropertyChanged("C"); 
    } 
} 


そしてBセッターと同じです。

関連する問題