Reputation: 710
I bind properties to controls in WPF. Values of properties are assigned/changed by recursive method which is in while loop. So values are assigned at rate of ~ 1 ms. Most of the time values are not changed at all but propertychanged event in setter fires even when property value is not changed. I was thinking that property setter should raise an event only when the value of a field is going to change. Here is simplified version of my code:
public sealed class FX : System.ComponentModel.INotifyPropertyChanged
{
public event PropertyChangedEventHandler PropertyChanged;
public void OnPropertyChanged(string PropertyName)
{
PropertyChangedEventHandler handler = PropertyChanged;
if (handler != null)
{
handler(this, new PropertyChangedEventArgs(PropertyName));
}
}
private bool _someBool1 = false;
public bool SomeBool1
{
get { return _someBool1; }
set
{
_someBool1 = value;
OnPropertyChanged("SomeBool1");
//MessageBox.Show("SomeBool1 : propertychanged event fired!");
}
}
}
According to http://www.codemag.com/Article/0907101 UI is the consumer of PropertyChanged events. While values of many properties are assigned constantly and as fast as possible that could result in unnecessary UI overhead. Is it ok to place OnPropertyChanged("SomeBool2"); in if statement? :
private bool _someBool2 = false;
public bool SomeBool2
{
get { return _someBool2; }
set
{
bool _someBool2OldValue = _someBool2;
_someBool2 = value;
if (_someBool2 != _someBool2OldValue)
{
OnPropertyChanged("SomeBool2");
//MessageBox.Show("SomeBool2 : propertychanged event fired!");
}
}
}
Have I misunderstood the idea "fire an event when property value is changed" or my code implementation is wrong?
Upvotes: 2
Views: 5453
Reputation: 9
Using the CommunityToolkit will now offer you a method that does this automatically: SetProperty(ref property, value)
This will only notify the property changed event only if the values are different.
Here is a link to the official docs.
Upvotes: 0
Reputation: 2504
Yes, in your first example, whenever that property setter is called, it will execute whatever code is in there, including your OnPropertyChanged handler, without prejudice. It is entirely valid to have whatever conditional logic you see fit in your setters/getters for properties. That's the beauty of properties over fields, in that you can decide to any fine detail you like how that value responds to data change, whether it's readonly or write-only, whatever you like.
For your second example, you can just use the 'value' keyword instead of creating a specific field.
Upvotes: 3
Reputation: 37770
I can't imagine, what this stuff with someBool2OldValue
is intended for:
set
{
if (_someBool2 != value)
{
_someBool2 == value;
OnPropertyChanged("SomeBool2");
}
}
Moreover, if you're running some loop, which brings your view model to the frequent property changes, it makes sense to stop firing PropertyChanged
event at all:
protected bool StopFiringPropertyChanged { get; set; }
protected virtual void OnPropertyChanged(string propertyName)
{
if (StopFiringPropertyChanged)
{
return;
}
// fire event
}
and fire it only after loop was finished for all properties, which could be changed during loop:
private void SomeMethodWithRecursiveLoop()
{
StopFiringPropertyChanged = true;
try
{
// do the work
}
finally
{
StopFiringPropertyChanged = false;
OnPropertyChanged("SomeProperty1");
OnPropertyChanged("SomeProperty2");
OnPropertyChanged("SomeProperty3");
}
}
Upvotes: 5