开发者

WPF binding to DataContext with class and subclass

I am playing with databinding in wpf and I encountered a problem. Here is my code:

MainWindow.xaml

<Window x:Class="TestWpf.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"开发者_如何学Python
        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));
        }
    }     
}

Now, the problem is that binding works fine, after I run the app. Also, values A.Number and B.Number are updating fine as I change them in textbox. But variable C in MyClass.C is updated only when app starts and never after. What do I need to change so that C updates when I change A.Number or B.Number. Thanks.


When updating your data model, do you change the Number directly on the MySubClass instances or do you assign new subclasses to the MyClass instance? i.e:

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

will not trigger OnPropertyChanged on the A (but will of course update A.Number). For this to work you have to do something like:

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

Updated answer. YOu could do this to catch any property changes in a and b.

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

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


What do I need to change so that C updates when I change A.Number or B.Number.

You need to listen for changes to A and B properties. It should work if you add this code to A setter:



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");
  }
}


and the same for B setter.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜