why don't people wrap DependencyProperties in a generic class?
I didn't like how verbose dp's are, since most of the code is just repeated, I just wrapped it in a generic class.
Having seen quite allot of sample code, I was wondering why more people aren't doing the same.
I haven't come across any problems to speak of in my demo application, and it makes the ViewModels easier to manage.
Sample:
class GenericDependancyProperty<T> : DependencyObject
{
// Value dependency property
public static readonly DependencyProperty ValueProperty =
DependencyProperty.Register( "Value", typeof( T ), typeof( GenericDependancyProperty ),
new FrameworkPropertyMetadata( (T)default(T),
new PropertyChangedCallback( OnValueChanged ) ) );
// getter/setter for the Value dependancy property
public T Value
{
get { return (T)GetValue( ValueProperty ); }
set { SetValue( ValueProperty, value ); }
}
// Handles changes to the Value property.
private static void OnValueChanged( DependencyObject d, DependencyPropertyChangedEventArgs e )
{
GenericDependancyProperty<T> target = (GenericDependancyProperty<T>)d;
T oldValue = (T)e.OldValue;
T newValue = target.Value;
target.OnValueChanged( oldValue, newValue );
}
// Provides derived classes an opportunity to handle changes to the Value property.
protected virtual void OnValueChanged( T oldValue, T newVal开发者_StackOverflow社区ue )
{
if ( ValueChanged != null )
{
ValueChanged( newValue );
}
}
// Value changed event
public event Action<T> ValueChanged;
}
Is this a bad idea?
It is not a bad idea, and well worth a try, but it will not work!
You have essentially defined a single dependency property named "Value". This will be OK if you only ever access it via your CLR wrapper (i.e. the get / set code for your Value property). However, much of the framework affects the dependency property directly. For example, style setters, animations will not be able to use your dependency property.
I too share your pain with the DP boilerplate code, which is why I came up with a declarative solution:
[DependencyPropertyDecl("Maximum", typeof(double), 0.0)]
[DependencyPropertyDecl("Minimum", typeof(double), 0.0)]
public partial class RangeControl : UserControl
{
...
}
The actual dependency properties are generated by a T4 template within Visual Studio.
https://blog.scottlogic.com/2009/08/18/declarative-dependency-property-definition-with-t4-dte.html
I think the main thing to point out is that you seem to be doing this to keep your view-model classes neater, but there isn't really any reason to use dependency properties in view-models to begin with.
As Colin's answer demonstrates, it is most common to declare dependency properties in derived/user controls. The view-model typically contains standard properties and implements INotifyPropertyChanged
.
Furthermore, it makes sense to put dependency properties in the derived control class itself instead of a separate generic/static class because you'll need to reference it statically:
MySlider.SpecialOpacityProperty
. If you have these things in a single class, then you couldn't have 2 properties with the same name (for different controls), or if you use a generic class you can't reference it in XAML.
Since your ValueProperty
is static, the value won't change no matter how you instantiate your class. I don't see how this would work.
Your solution is not feasible, flexible and not scalable at all.
Since C# only allows single base class, with your approach, every class can have one DP
at once.
That is why it won't work.
What you should do to ease your pain is use snippets
or code generation
as Colin
mentioned.
And remember, we all share the same pain.
精彩评论