【问题标题】:Designing the class inheritance of my custom control设计我的自定义控件的类继承
【发布时间】:2012-01-13 15:52:56
【问题描述】:

我正在创建几个不同的自定义控件,每个控件都实现不同的基本控件,但它们都将获得一些共同的属性和功能。所以我想将那些通用属性(以及它们的通用 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; }
}

【问题讨论】:

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


    【解决方案1】:

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

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

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

    【讨论】:

      【解决方案2】:

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

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

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

      这看起来确实是多重继承的一个很好的论据。

      【讨论】:

        猜你喜欢
        • 2015-10-05
        • 2012-12-17
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2021-05-06
        • 1970-01-01
        • 2011-08-01
        • 1970-01-01
        相关资源
        最近更新 更多