0

我对 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 个字段......)

我哪里错了?您的帮助将不胜感激。

4

1 回答 1

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的 's 。DataContext同样,我不建议您这样做,您最好应用第一个解决方案!

于 2012-09-07T21:01:17.473 回答