表单和用户控件的一个基类

时间:2017-11-28 14:29:35

标签: c# forms winforms user-controls base-class

我有一个Form,有几种输入验证方法。我希望在几个FormUserControl之间共享此验证逻辑。什么应该是基类的类型?它不能是Form,因为它也会用于UserControl,它不能是UserControl,因为它也会用于Form

我的直觉告诉我,解决方案可能涉及泛型,但我不确定。

注意:“验证逻辑”我指的是实现,因此接口不是解决方案。

编辑(使问题更清晰):有一个单独的类来实际验证输入。但是,我使用ErrorProvider来指示用户输入无效。我的InputValidator类使用Form调用UserControl / ErrorProvider内的方法向用户显示错误。我只是不想为每个Form / UserControl复制粘贴此方法。

3 个答案:

答案 0 :(得分:3)

您无法创建同时处理Forms和UserControls的基类。但是,您可以为表单创建基类,为UserControls创建另一个基类。

此外,创建一个接口,两个基类都实现并发布您需要在验证器中使用的成员。

通过这种方法,重复的代码量至少减少到两个位置。请注意,有一些OOP实践在Windows窗体(例如抽象类)的上下文中不起作用,因为设计者引入了一些限制。

原始答案:
在这种情况下,最好的选择是将验证逻辑移动到它自己的单独类中。您可以使用Forms和UserControls中的这个新类。

如果您需要在验证期间引用Form或UserControl,则可以使用ContainerControl类型的参数。此类是Form和UserControl的基类。这样,您就可以创建适用于从ContainerControl继承的所有类的共享逻辑。

答案 1 :(得分:2)

使用合成而不是继承。请参阅:Composition over inheritance(维基百科)。

您的表单必须继承自Form或其他继承自Form的表单。您的用户控件必须继承自UserControl或继承自UserControl的其他用户控件。你不能改变它,因此你不能为它们提供自己的基类。

相反,请在单独的类中实现验证逻辑,并在表单和用户控件中使用它。

public partial class MyForm : Form
{
    private readonly MyValidation _validation;

    public Myform()
    {
        InitializeComponent();
        _validation = new MyValidation(errorProvider1);
    }

    //TODO: use _validation instead of inherited validation logic.
}

我无法向您提供有关如何准确实现此问题的更多详细信息,因为我不知道您的验证是什么。

答案 2 :(得分:1)

首先是第一件事 - 我认为Olivier的答案非常好,我建议你使用它。
但是,虽然您无法更改FormUserControl的基类,但仍然有一种方法只使用接口和扩展方法编写一次方法 - 这就是我的意思我想在这里给出答案。

界面:

internal interface IValidatable
{
    ErrorProvider ErrorProvider {get;} 
}

扩展类:

internal static class IValidatableExtensions
{
    internal void ShowValidationResult(this IValidatable self, ValidationResult result)
    {
    // Here you can use self.ErrorProvider to show your results
    }
}

现在,您可以让表单和用户控件实现IVilidatable接口,在验证类中只需调用ShowValidationResult方法。

同样,我只是简单地向验证实例发送一个对errorProvider的引用,正如Olivier在他的回答中所证明的那样,但是这种技术在其他情况下可能会有用,所以我想我最好自己添加一个答案。