我对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场......)
我哪里错了? 非常感谢您的帮助。
答案 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}}。同样,我不建议你这样做,你最好不要应用第一个解决方案!