简体   繁体   English

WPF与类和子类绑定到DataContext

[英]WPF binding to DataContext with class and subclass

I am playing with databinding in wpf and I encountered a problem. 我正在使用wpf中的数据绑定,我遇到了一个问题。 Here is my code: 这是我的代码:

MainWindow.xaml 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 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 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 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. 此外,值A.Number和B.Number正在更新,因为我在文本框中更改它们。 But variable C in MyClass.C is updated only when app starts and never after. 但MyClass.C中的变量C仅在应用程序启动时更新,从不更新。 What do I need to change so that C updates when I change A.Number or B.Number. 当我更改A.Number或B.Number时,我需要更改以便C更新。 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? 更新数据模型时,是否直接在MySubClass实例上更改数字,还是将新的子类分配给MyClass实例? ie: 即:

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). 不会在A上触发OnPropertyChanged(但当然会更新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. 你可以这样做来捕捉a和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. 当我更改A.Number或B.Number时,我需要更改以便C更新。

You need to listen for changes to A and B properties. 您需要侦听A和B属性的更改。 It should work if you add this code to A setter: 如果您将此代码添加到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. 和B setter一样。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM