如何在不同的自定义控件之间共享行为?

时间:2017-12-17 15:33:17

标签: c# winforms inheritance

我有两个自定义控件:CustomTextBoxCustomNumericUpDown。我希望他们有一个共享行为,它包含一些方法和一些属性。

我提出的解决方案:

  1. 两者都应该扩展包含共享行为的抽象类。问题是扩展TextBox另一个扩展NumericUpDown。我想不出两种方法都可以继承我的抽象类,除了多重继承,这在C#中是不允许的。
  2. 实现共享接口。这显然很愚蠢,因为接口无法实现。
  3. 使用扩展方法。更具体地说,使它们共享一个接口,并为该接口创建扩展方法。问题是you cannot (currently) have extension properties in C#,我真的不想使用the principle of least astonishment的实际方法来实现getter和setter。
  4. 这个问题有一个优雅的方法,不涉及重复代码吗?

    修改

    例如,我希望CustomTextBoxCustomNumericUpDown都有ValidateInput()方法和ValidationRules属性。即,我想为他们两个添加一个方法和一个属性。

3 个答案:

答案 0 :(得分:1)

这是我的想法,

创建具有两个控件的常用功能的类

将它注入两个控件初始化,可以访问公共类的常用函数

@ViewChild(RadSideDrawerComponent) 
public drawerComponent: RadSideDrawerComponent;

答案 1 :(得分:1)

远非优雅,但如果您不需要依赖派生控件的特定实现细节,则可以使用接口的组合(以强制实现所需的属性和方法)和{ {3}}(封装/集中共享行为)。

派生控件中接口的实现完全是样板文件,并始终委托其他地方。

public class ValidationService
{
    public void RegisterRules(Control control, string[] rules)
    {
        // store rules
    }

    public string[] GetRules(Control control)
    {
        // retrieve rules
    }

    public void Validate(Control control)
    {
        // validate
    }
}

public interface IValidatable
{
    ValidationService ValidationService { get; set; }
    string[] Rules { get; set; }
    void ValidateControl();
}

public class MyTextBox : TextBox, IValidatable
{
    public ValidationService ValidationService { get; set; }

    public string[] Rules
    {
        get => ValidationService.GetRules(this);
        set => ValidationService.RegisterRules(this, value);
    }

    public void ValidateControl()
    {
        ValidationService.Validate(this);
    }
}

public class MyNumericUpDown : NumericUpDown, IValidatable
{
    public ValidationService ValidationService { get; set; }

    public string[] Rules
    {
        get => ValidationService.GetRules(this);
        set => ValidationService.RegisterRules(this, value);
    }

    public void ValidateControl()
    {
        ValidationService.Validate(this);
    }
}

但是,如果您的验证行为依赖于派生控件的特定细节,则此方法会变得混乱。

答案 2 :(得分:0)

创建一个包含常用功能的基类。为您需要的每个控件扩展该类,并将控件放在该类中。

for n in range(1,K+1) : long_div(w,5*5,w)