Reputation: 25
I have question about DataContext changes and I build example for understand this aspect. I have MainUserControl on MainWindow. MainUserControl consists of number of User Controls. One of such User Controls is SubUserControl1.
<Window x:Class="WpfApplicationUcBindingQuestion.MainWindow">
<Grid>
.....
<uc:MainUserControl />
</Grid>
</Window>
<UserControl x:Class="WpfApplicationUcBindingQuestion.MainUserControl">
<Grid>
.....
<uc:SubUserControl1 x:Name="subUserControl1" />
</Grid>
</UserControl>
And in MainWindow I have object of class Info. Class Info consists of a few inner classes. One of them is, lets say, SubInfo. Both Info and SubInfo classes inherits from INotifyPropertyChanged.
And this is the code of them:
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));
}
}
I want to set DataContext for MainUserControl to be object of class Info and for SubUserControl1 DataContext will be Info.SubInfo.
The following code describes this:
<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;
}
When new subInfo arrived I update inner object subInfo inside info object: (This is function of MainWindow)
private void OnUpdateData()
{
SubInfo arrivedSubInfo = new SubInfo();
arrivedSubInfo.SubString = "newString";
m_info.SubInfo = arrivedSubInfo;
}
I want to see that DataContext for subUserControl1 is also changed.
But it doesn't happened and TextBox inside SubUserControl1 is not updated and doesn't show "newString".
(Note: If I write inside OnUpdateData() function the following:
m_info.SubInfo.SubString = arrivedSubInfo.SubString;
(copy field-field and not whole object) it works, but I dont 'want copy 50 field...)
Where I'm wrong? Your help will be really appreciated.
Upvotes: 0
Views: 561
Reputation: 6651
Your problem is the following:
In your constructor, when you do that:
this.DataContext = info;
this.subUserControl1.DataContext = info.SubInfo;
You will set the DataContext ONLY once. Which means it will never change unless you write subUserControl1.DataContext = someNewDataContext
somewhere.
What you can do to solve this :
The "proper solution":
Use a binding. In your XAML, just write:
<uc:SubUserControl1 x:Name="subUserControl1" DataContext="{Binding
SubInfo, UpdateSourceTrigger=PropertyChanged}" />
This will work, assuming that your SubInfo
property fires the OnPropertyChanged
event when it is set.
The "ugly solution":
Explicitly set your UserControl
's DataContext
in code-behind when you need it. Again, I wouldn't advise that and you are better off applying the first solution!
Upvotes: 3