Event for "attempted" property changes
(using .Net 3.5) I have a routine that imports settings from an external datasource, after which I need to display a pseudo-log to the user detailing which properties have been updated. Usually I would track property updates through the property_changed events. However, when the value from the datasource happens to already equal the property value, then property_changed event never gets raised, even if the property set was called. But I still need to display such properties to the user as being "updated" from the datasource.
What is the common pattern here? Do I need another event (in addtion to property_changed) in my property setters- "pr开发者_如何学Gooperty_attemptedset"?
Edit: So one suggestion is that I simply not do an equality check in the property setter, so that "property_changed" gets fired no matter what. But I've always been told to filter for actual value changes. Is that not best practice?
Well, it's pretty common to avoid raising the PropertyChanged event when you're not actually changing the property's value... but there's no rule that says you have to. Just remove any logic in the setter which checks the new value against the current value.
if you write your properties like this:
public string LastName{
get { return lastName; }
set {
lastName = value;
RaisePropertyChanged("LastName");
}
}
It should always fire the PropertyChanged
-event, even if the value is the same. You don't need to fire any additional events for this.
EDIT
in addition to your edit: Yes, it is considered best practice to check for actual value changes, but if your scenario needs to track non-value changes, I don't see why you can't change it. "Best practice" doesn't mean "Break-this-rule-and-go-to-jail" thing right?
But in case these classes have any other observers, which also rely on the common PropertyChanged behavior, you can always extend the properties and throw another (custom) event like you mentioned:
public event PropertyChangedEventHandler AttemptedPropertyChanged;
public void RaiseAttemptedPropertyChanged(string propName)
{
if (AttemptedPropertyChanged != null)
{
AttemptedPropertyChanged(this, new PropertyChangedEventArgs(propName));
}
}
public string LastName{
get { return lastName; }
set {
RaiseAttemptedPropertyChanged("LastName");
if (lastName == value) return;
lastName = value;
RaisePropertyChanged("LastName");
}
}
It sounds like your next step based on what you've written is to sometimes prevent the change. If so, I'd introduce a new event like BeforePropertySet, and pass an event object that allows cancelling.
This keeps with best practices (preventing the eventuality where someone some day comes along to use propertychanged the conventional way and can't figure out why their code doesn't work), clarifies what you're doing, and lets you separate concerns a bit better.
精彩评论