I have a ViewModelBase class as follows:
public class ViewModelBase : INotifyPropertyChanged
{
public event PropertyChangedEventHandler PropertyChanged;
public void OnPropertyChanged(string propertyName)
{
if (PropertyChanged != null)
{
PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
}
}
public static event PropertyChangedEventHandler GlobalPropertyChanged = delegate { };
public static void OnGlobalPropertyChanged(string propertyName, Type className)
{
GlobalPropertyChanged(className,new PropertyChangedEventArgs(propertyName));
}
}
Now, I have another viewModel called GroupViewModel which inherits ViewModelBase:
public class GroupViewModel : ViewModelBase
{
public GroupsViewModel()
{
CurrentGroup = new Group();
}
private static Group _currentGroup;
public static Group CurrentGroup
{
get
{
return _currentGroup;
}
set
{
_currentGroup = value;
OnGlobalPropertyChanged("CurrentGroup", typeof(Group));
}
}
}
Now in Groups.xaml Page :
<Grid DataContext="{Binding CurrentGroup}">
.....
.....
<TextBlock Text="{Binding GroupName, TargetNullValue=''}" />
.....
.....
</Grid>
I have another ViewModel called MainWindowViewModel, I try to save CurrentGroup to Database like below code and then I set CurrentGroup = new Group();
but in Group.xaml the text of TextBox is not cleared :
Group group = GroupViewModel.CurrentGroup;
db.Groups.Add(group);
db.SaveChanges();
GroupViewModel.CurrentGroup = new Group();
Update:
If I use the below code in GroupsViewModel, the output is as expected. I mean View is updated when Static property changes.
public static event EventHandler<PropertyChangedEventArgs> StaticPropertyChanged
= delegate { };
private static void NotifyStaticPropertyChanged(string propertyName)
{
StaticPropertyChanged(null, new PropertyChangedEventArgs(propertyName));
}
If I use that same code in ViewModelBase (Please note that GroupsViewModel inherits ViewModelBase) then View is not updated when value of static property changes. Also I have marked the NotifyStaticPropertyChanged as public in this case to avoid the compile time errors like errors about protection level.
For Static PropertyChanged
you have to create generic static event like this in your class:
public static event EventHandler<PropertyChangedEventArgs> StaticPropertyChanged
= delegate { };
private static void NotifyStaticPropertyChanged(string propertyName)
{
StaticPropertyChanged(null, new PropertyChangedEventArgs(propertyName));
}
and you have to call like you use to do instance properties:
NotifyStaticPropertyChanged("CurrentGroup");
But main catch is in XAML where you are binding -
You'll use parentheses around the namespace, class, and property because WPF binding engine parse the path as ClassName.PropertyName rather than PropertyName.PropertyName.
So, it will be like this:
<Grid DataContext="{Binding Path=(local:GroupViewModel.CurrentGroup)}">
.....
.....
<TextBlock Text="{Binding GroupName, TargetNullValue=''}" />
.....
.....
</Grid>
Source here INPC for static properties.
UPDATE
If I use that same code in ViewModelBase (Please note that GroupsViewModel inherits ViewModelBase) then View is not updated when value of static property changes.
StaticPropertyChangedEvent
have to be in same class where property resides. It won't work like traditional INotifyPropertyChanged
for instance properties.
I don't have any MSDN documentation to assert that but I verified it by tweaking event code a bit to see if XAML is hooking onto StaticPropertyChangedEvent
from XAML.
Replace event code to this and you can see yourself:
private static event EventHandler<PropertyChangedEventArgs> staticPC
= delegate { };
public static event EventHandler<PropertyChangedEventArgs> StaticPropertyChanged
{
add { staticPC += value; }
remove { staticPC -= value; }
}
protected static void NotifyStaticPropertyChanged(string propertyName)
{
staticPC(null, new PropertyChangedEventArgs(propertyName));
}
Put a breakpoint on add and you will see it will get hit since WPF binding engine internally hook to it to listen to static property changed events.
But as soon as you move that to base class ViewModelBase, breakpoint won't get hit. Since, WPF haven't hook to it so any changes in property won't update UI obviously.
Whenever you want to update the property changes of a particular data type, you need to implement the INotifyPropertyChanged
interface in that data type. This means that if you want to update the property changes of a view model, in your case a change to the CurrentGroup
object, you'd need to implement the INotifyPropertyChanged
interface in your view model.
However, it seems as though you actually want to update the property changes that have been made inside the CurrentGroup
class (to clear them), so in that case, you'd need to implement the INotifyPropertyChanged
interface in your CurrentGroup
class as well. I believe that that is what @Silvermind meant by You would need to raise the event that is associated with the instance.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With