我有两个自定义控件:CustomTextBox
和CustomNumericUpDown
。我希望他们有一个共享行为,它包含一些方法和一些属性。
我提出的解决方案:
TextBox
另一个扩展NumericUpDown
。我想不出两种方法都可以继承我的抽象类,除了多重继承,这在C#中是不允许的。是否有一个优雅的方法来解决这个问题,不涉及重复代码?
编辑:
例如,我希望CustomTextBox
和CustomNumericUpDown
都有ValidateInput()
方法和ValidationRules
属性。即,我想为它们两者添加一个方法和一个属性。
远非优雅,但如果您不需要依赖派生控件的特定实现细节,您可以使用接口的组合(以强制执行您想要的属性和方法)和delegation(以封装) /集中共享行为)。
派生控件中接口的实现完全是样板文件,并始终在其他地方委托。
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);
}
}
但是,如果您的验证行为依赖于派生控件的特定详细信息,则此方法会变得混乱。
这是我的想法,
创建具有两个控件的常用功能的类,
将它注入两个控件初始化,可以访问公共类的常用函数
public class CommonFunctions
{
public void ValidateInput(Object sender){
// do your validation logic
}
}
public class CustomTextBox : TextBox
{
private CommonFunctions _commonFunctions;
public CustomTextBox(CommonFunctions commonFunctions)
{
_commonFunctions = commonFunctions;
}
private void Control_TextChanged(Object sender,EventArgs e)
{
_commonFunctions.ValidateInput(sender);
}
}
public class CustomNumericUpDown : NumericUpDown
{
private CommonFunctions _commonFunctions;
public CustomNumericUpDown(CommonFunctions commonFunctions)
{
_commonFunctions = commonFunctions;
}
private void Control_TextChanged(Object sender,EventArgs e)
{
_commonFunctions.ValidateInput(sender);
}
}
创建一个包含通用功能的基类。为您需要的每个控件扩展该类,并将控件放在该类中。
public class MyUserControl : UserControl
{
public MyUserControl() : base()
{
}
// add common behaviour here (validation, etc)
}
public class MyTextBox : MyUserControl
{
public MyTextBox() : base()
{
Add(new TextBox());
}
...
}