In my situation, a UserControl
was nested in a View
and when I tried Binding
to a property within the UserControl
, the framework was looking for the property in the ViewModel
, which does not exist. To solve this, I had to specify ElementName
.
MyControl.xaml:
<UserControl
...
x:Name="MyUserControl">
...
<Label Content="{Binding MyProperty, ElementName=MyUserControl}"
...
MyControl.xaml.cs:
public partial class MyControl: UserControl, INotifyPropertyChanged
{
...
private string _myProperty = "";
public string MyProperty
{
get => _myProperty ;
set
{
if (value == _myProperty ) return;
_myProperty = value;
OnPropertyChanged();
}
}
public event PropertyChangedEventHandler PropertyChanged;
protected virtual void OnPropertyChanged([CallerMemberName] string propertyName = null)
{
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
}
...
I had this problem and here is what I was doing wrong...
Note: I Had INotifyPropertyChanged coded correctly.
In my View, I had
<SomeView.DataContext>
<SomeViewModel/>
<SomeView.DataContext/>
...and this calls the constructor of the VM (creating an instance to point to / to be bound to).
In another class (in the ViewModel code for my program's Main Window) I was also instantiating the ViewModel(s), i.e.:
private SomeAstractBaseViewModel someViewModel = new SomeViewModel();
private SomeAstractBaseViewModel someOtherViewModel = new SomeOtherViewModel();
They both inherited from a superclass and I was switching back and forth between instances showing different Views in a section of the Main Window - as per my intention.
How all that is wired up is another question, but when I remove the problematic xaml (at the top of this answer) that was previously instantiating another "unused" instance of the ViewModel, the View would update as per INotifyPropertyChanged mechanisms.
You need to implement INotifyPropertyChanged
in your ViewModel order to notify the View that the property has changed.
Here's a link to the MSDN page for it: System.ComponentModel.INotifyPropertyChanged
The most important thing to note is that you should raise the PropertyChanged
event in your property setter.
Add binding mode two way, because by default Textblock's binding mode is one way
<TextBlock HorizontalAlignment="Left" Name="StatusText" Margin="0,20" TextWrapping="Wrap" Text="{Binding StatusText, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}">
... Status ...
</TextBlock>
and also, of course you need to implement INotifyPropertyChanged for the purpose, refer to this link for how to implement.
Your view model needs to implement INotifyPropertyChanged
, and you need to raise it every time one of your property changes (ie in the setter).
Without it WPF has no way of knowing that the property has changed.
When working with DataModels you have to be sure the model is complete at intial load. So if you do this: this.DataContext = mainViewModel and some parts of you mainViewModel are NOT loaded (=null) then you are not able to bind them. Example, I have a Model within that model an object Program. I bind to Text of a TextBlock to Model.Program.Name. The Program object is not connected at initial load so you will have to rebind to a loaded object after because otherwise no notifications can be send.