设计我的自定义控件的类继承

时间:2012-01-13 15:52:56

标签: design-patterns inheritance custom-controls class-design

我正在创建几个不同的自定义控件,每个控件都实现不同的基本控件,但它们都会添加一些常见的属性和功能。所以我想要将这些公共属性(使用它们的公共getter和setter)以及将功能重复放入抽象类中。但是我很难围绕如何构建控件及其基础来实现我的抽象类和我正在构建的基本Web控件。任何人都可以帮助我吗?

我正在构建的一些控件

public class AssetDataStringControl : TextBox
public class AssetDataIntegerControl : TextBox
public class AssetDataUrlControl : CompositeControl
public class AssetDataListBoxControl : ListBox
public class AssetDataDropDownControl : DropDownList

我的抽象类

public abstract class AssetDataInputControlBase<T> : Control, 
    IAssetDataInputControl<T>
{
    protected virtual int AssetId
    {
        get
        {
            object o = ViewState["AssetId"];
            return o == null ? 0 : (int)o;
        }
        set { ViewState["AssetId"] = value; }
    }

    protected virtual AssetStructureField StructureField
    {
        get
        {
            object o = ViewState["StructureField"];
            return o == null ? null : (AssetStructureField)o;
        }
        set { ViewState["StructureField"] = value; }
    }

    public abstract T DataField { get; set; }
}

2 个答案:

答案 0 :(得分:0)

一个建议:使AssetDataInputControlBase成为Canvas并在其中放置您想要的任何Control。作为一个画布,它的行为很像一个控件。您需要的任何Control特定方法/属性都需要向调用Control方法的ADICB添加方法。如果它们中有很多,那么这个想法就不那么好了。

另一个建议:您的控件可以实现一个接口,该接口具有返回类似AssetDataInputControlBase的方法,仅在这种情况下ADICB不会实现Control或其他任何操作。相反,它只有AssetID,AssetStructureField和DataField(以及以后需要的其他东西)。因此,您的控件(例如AssetDataStringControl)只是扩展一个Control(例如TextBox),另外还包含对ADICB对象的引用。

这假设ADICB的值与Control(TextBox,比如说)相当独立。如果StructureField的get方法需要来自TextBox的各种信息,并且需要以不同的方式获取它,而不是ListBox,那么一切都会变得混乱,你需要一个更好的解决方案。如果不是,则您的控件只是TextBox,ListBox等的扩展,并添加了一个对ADICB对象的引用。一个ADICB类,无论多么复杂,一旦编写就可以被所有控件使用。

这看起来像是多重继承的好参数。

答案 1 :(得分:0)

忘掉abstract。在我看来,.NET Web控件继承链在功能上层层叠叠,而不是在糟糕的“最终产品”控件上强制执行大量实现。我会看看我是否可以顺其自然。这意味着从适当的类继承以获得构建的基础(双关语)。

看起来您想要构建复合Web控件。 仔细阅读 System.Web.UI命名空间上的文档。考虑从System.Web.UI.CompositeControl继承。它为您提供了一个子控件集合和一些内置渲染。它实现了INamingContainer来管理子控件唯一ID。

只是想一想,也许你可以创建一个在运行时构造自定义组合的类(你能说factory pattern吗?)。 仔细阅读 System.Web.UI命名空间上的文档无论如何,基础已经知道如何渲染复合。每个子控件(文本框,列表框等)都知道如何渲染自身。在工厂中,每个子控件都被赋予它的数据绑定。然后将它们注入到自定义的CompositeControl构造函数中。