I've inherited a Silverlight project with dubious code quality overa开发者_运维知识库ll, and there is one construct that I'm not sure whether I should touch it:
public SomeClass Self
{
get
{
return this;
}
}
It is used in XAML Bindings, with parameters, sometimes complex like this:
Visibility="{Binding Self, ConverterParameter=!, Converter={StaticResource SmartAssConverter}}"
And it is used in a PropertyChanged notification (MVVM Light):
RaisePropertyChanged("Self");
So, is there something preventing me from just doing this:
Visibility="{Binding ConverterParameter=!, Converter={StaticResource SmartAssConverter}}"
which, I've tested, still shows just fine?
Rephrasing my question, is the necessity to 'raise property changed' forcing this kind of (IMHO ugly) construct?
Edit: rephrasing again, is there a more elegant solution to notify binded controls that their target has changed, or should I look into reworking the Converters?
What if the object (i.e. Self
) changes? When using the Self
property you can leverage the INotifyPropertyChanged interface to tell the binding to updated. If you remove the property, then how would you update?
You can try doing RaisePropertyChanged(string.Empty)
, but I don't think that would work.
Generally the converters would just be passed the properties they need, not the entire object. But in Silverlight, there is no MultiBinding so you are limited to a single property.
You can either add a new property to your object that performs the same operation as the converter, or wrap it with another object that adds the property. This is generally the role of a view-model.
The code you have shown is a little clumsy looking, but I don't think it is so bad that it need to be reworked. You are right, you can remove the path altogether and this will work for a one-time evaluation of the binding. However, the worrying part is where the code raises a property change for 'Self' in order to re-evaluate the bindings (great hack ... I'll remember that for future use!)
The correct approach here is to change the DataContext itself, this is effectively a change of 'self' and will cause all binding to be re-evaluated.
Personally, I would not spend too long on this, I have seen much much worse!
I typically implement the IChangeTracking and INotifyPropertyChanged interfaces, and then do the following in the default constructor:
public SomeClass()
{
this.PropertyChanged += new PropertyChangedEventHandler(OnNotifiedOfPropertyChanged);
}
private void OnNotifiedOfPropertyChanged(object sender, PropertyChangedEventArgs e)
{
if (e != null && !String.Equals(e.PropertyName, "IsChanged", StringComparison.Ordinal))
{
this.IsChanged = true;
}
}
The IsChanged property raises property change notifications, and so you can bind to IsChanged
to be notified when the class has been modified without needing to expose the class itself as a 'Self' property.
精彩评论