为什么内部对象的DataContext没有更新?

时间:2012-09-07 20:51:17

标签: wpf datacontext

我对DataContext更改有疑问,我构建了一个例子来理解这个方面。 我在MainWindow上有MainUserControl。 MainUserControl包含许多用户控件。 其中一个用户控件是SubUserControl1。

<Window x:Class="WpfApplicationUcBindingQuestion.MainWindow">
    <Grid>
        .....
      <uc:MainUserControl />
    </Grid>
</Window>

<UserControl x:Class="WpfApplicationUcBindingQuestion.MainUserControl">
<Grid>
.....
    <uc:SubUserControl1 x:Name="subUserControl1" />
</Grid>
</UserControl>

在MainWindow中,我有类Info的对象。类信息由几个内部类组成。 其中一个就是SubInfo。 Info和SubInfo类都继承自INotifyPropertyChanged。

这是他们的代码:

public class Info : INotifyPropertyChanged
{
    private SubInfo m_subInfo = new SubInfo();

    public Info()
    {
    }

    public SubInfo SubInfo 
    {
        get
        {
            return m_subInfo;
        }
        set
        {
            m_subInfo = value;
            OnPropertyChanged("SubInfo");
        }      
    }

    public event PropertyChangedEventHandler PropertyChanged;

    protected void OnPropertyChanged(string propertyName)
    {
        PropertyChangedEventHandler handler = PropertyChanged;
        if (handler != null)
            handler(this, new PropertyChangedEventArgs(propertyName));
    } 
}

public class SubInfo: INotifyPropertyChanged
{
    private string m_subString = "subStr";

    public SubInfo()
    {
    }

    public string SubString 
    {
        get
        {
            return m_subString;
        }
        set
        {
            m_subString = value;
            OnPropertyChanged("SubString");
        }      
    }

    public event PropertyChangedEventHandler PropertyChanged;

    protected void OnPropertyChanged(string propertyName)
    {
        PropertyChangedEventHandler handler = PropertyChanged;
        if (handler != null)
            handler(this, new PropertyChangedEventArgs(propertyName));
    } 
}

我想将MainUserControl的DataContext设置为类Info的对象 和对于SubUserControl1 DataContext将是Info.SubInfo。

以下代码描述了这一点:

<UserControl x:Class="WpfApplicationUcBindingQuestion.SubUserControl1">
   <Grid>
      .....
    <TextBox Text="{Binding Path=SubString}"/> 
   </Grid>
</UserControl>

public MainUserControl()
{
        InitializeComponent();

        MainWindow mainWnd = (MainWindow)Application.Current.MainWindow;

        Info info = mainWnd.Info;
        this.DataContext = info;

        this.subUserControl1.DataContext = info.SubInfo;
}

当新的subInfo到达时,我更新了info对象中的内部对象subInfo: (这是MainWindow的功能)

private void OnUpdateData()
{
    SubInfo arrivedSubInfo = new SubInfo();
    arrivedSubInfo.SubString = "newString";

    m_info.SubInfo = arrivedSubInfo;
}

我想看到subUserControl1的DataContext也发生了变化。

但它没有发生,并且SubUserControl1中的TextBox没有更新 并且不显示“newString”。

(注意:如果我在OnUpdateData()函数内写入以下内容:

m_info.SubInfo.SubString = arrivedSubInfo.SubString;

(复制字段 - 而不是整个对象)它的工作原理, 但我不想复制50场......)

我哪里错了? 非常感谢您的帮助。

1 个答案:

答案 0 :(得分:3)

您的问题如下:

在你的构造函数中,当你这样做时:

    this.DataContext = info;

    this.subUserControl1.DataContext = info.SubInfo;

您只需设置一次DataContext。这意味着除非你在某处写subUserControl1.DataContext = someNewDataContext,否则它永远不会改变。

你可以做些什么来解决这个问题:

“正确解决方案”:

使用绑定。在你的XAML中,只需写下:

<uc:SubUserControl1 x:Name="subUserControl1" DataContext="{Binding
SubInfo, UpdateSourceTrigger=PropertyChanged}" />

这将有效,假设SubInfo属性在设置时触发OnPropertyChanged事件。

“丑陋的解决方案”:

在您需要时,在代码隐藏中明确设置UserControl的{​​{1}}。同样,我不建议你这样做,你最好不要应用第一个解决方案!