为什么人们不将DependencyProperties包装在泛型类中?

时间:2020-12-11 20:04:53

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.

我不喜欢详细的dp,因为大多数代码都是重复的,我只是把它包装在一个泛型类中。

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.

我在演示应用程序中没有遇到任何问题,它使ViewModel更易于管理。

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 newValue )
    {
        if ( ValueChanged != null )
        {
            ValueChanged( newValue );
        }
    }

    // Value changed event
    public event Action<T> ValueChanged;
}

Is this a bad idea?

这是一个坏主意吗?

4 个解决方案

#1


13  

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.

您基本上定义了一个名为“Value”的依赖项属性,如果您只通过CLR包装器(即Value属性的get / set代码)访问它,这将是正常的,但是,大部分框架都会影响依赖项财产直接。例如,样式设置器,动画将无法使用您的依赖项属性。

I too share you pain with the DP boiler-plate code, which is why I came up with a declarative solution:

我也用DP锅炉板代码分享你的痛苦,这就是我想出一个声明性解决方案的原因:

[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.

实际依赖项属性由visual studio中的T4模板生成。

http://www.scottlogic.co.uk/blog/colin/2009/08/declarative-dependency-property-definition-with-t4-dte/

http://www.scottlogic.co.uk/blog/colin/2009/08/declarative-dependency-property-definition-with-t4-dte/

Colin E.

科林E.

#2


1  

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.

正如Colin的回答所示,最常见的是在派生/用户控件中声明依赖项属性。视图模型通常包含标准属性并实现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.

此外,将依赖项属性放在派生控件类本身而不是单独的泛型/静态类中是有意义的,因为您需要静态引用它:MySlider.SpecialOpacityProperty。如果你在一个类中有这些东西,那么你就不能拥有2个具有相同名称的属性(对于不同的控件),或者如果使用泛型类,则无法在XAML中引用它。

#3


0  

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.

由于您的ValueProperty是静态的,因此无论您如何实例化类,该值都不会更改。我不明白这是怎么回事。

#4


0  

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.

由于C#只允许单个基类,因此使用您的方法,每个类可以同时拥有一个DP。

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.

请记住,我们都有同样的痛苦。

#1


13  

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.

您基本上定义了一个名为“Value”的依赖项属性,如果您只通过CLR包装器(即Value属性的get / set代码)访问它,这将是正常的,但是,大部分框架都会影响依赖项财产直接。例如,样式设置器,动画将无法使用您的依赖项属性。

I too share you pain with the DP boiler-plate code, which is why I came up with a declarative solution:

我也用DP锅炉板代码分享你的痛苦,这就是我想出一个声明性解决方案的原因:

[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.

实际依赖项属性由visual studio中的T4模板生成。

http://www.scottlogic.co.uk/blog/colin/2009/08/declarative-dependency-property-definition-with-t4-dte/

http://www.scottlogic.co.uk/blog/colin/2009/08/declarative-dependency-property-definition-with-t4-dte/

Colin E.

科林E.

#2


1  

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.

正如Colin的回答所示,最常见的是在派生/用户控件中声明依赖项属性。视图模型通常包含标准属性并实现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.

此外,将依赖项属性放在派生控件类本身而不是单独的泛型/静态类中是有意义的,因为您需要静态引用它:MySlider.SpecialOpacityProperty。如果你在一个类中有这些东西,那么你就不能拥有2个具有相同名称的属性(对于不同的控件),或者如果使用泛型类,则无法在XAML中引用它。

#3


0  

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.

由于您的ValueProperty是静态的,因此无论您如何实例化类,该值都不会更改。我不明白这是怎么回事。

#4


0  

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.

由于C#只允许单个基类,因此使用您的方法,每个类可以同时拥有一个DP。

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.

请记住,我们都有同样的痛苦。