设计我的自定义控件的类继承
我正在创建几个不同的自定义控件,每个控件都实现不同的基本控件,但它们都将添加一些常见的属性和功能。因此,我想将这些通用属性(及其通用的 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; }
}
I am creating a couple different custom controls, each of which implement different base controls, but they all will be getting some common properties and functionality added to them. So I was wanting to place those common properties (with their common getters and setters) and the duplication of the functionality into an abstract class. But I'm having a hard time wrapping my head around how to architect the controls and its bases to allow the implementation of both my abstract class and the base web control I'm building on top of. Can anyone help me out?
Some of the controls I'm building
public class AssetDataStringControl : TextBox
public class AssetDataIntegerControl : TextBox
public class AssetDataUrlControl : CompositeControl
public class AssetDataListBoxControl : ListBox
public class AssetDataDropDownControl : DropDownList
My abstract class
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; }
}
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
忘记
抽象
。在我看来,.NET Web 控件继承链是按功能分层的,而不是在较差的“最终产品”控件上强制执行大量实现。我想看看是否可以顺其自然。这意味着从适当的类继承以获得构建的基础(双关语)。看起来您想构建复合 Web 控件。 仔细阅读有关
System.Web.UI
命名空间的文档。考虑继承System.Web.UI.CompositeControl
。它为您提供了一个子控件集合和一些内置渲染。它实现了INamingContainer
来管理子控件的唯一ID。只是一个想法,也许您可以创建一个在运行时构造自定义组合的类(您可以说
工厂模式
吗?)。 仔细阅读有关System.Web.UI
命名空间的文档无论如何,基础已经知道如何渲染组合。每个子控件(文本框、列表框等)都知道如何呈现自身。在工厂中,每个子控件都被赋予了数据绑定。然后将它们注入到您的自定义 CompositeControl 构造函数中。Forget about
abstract
. Seems to me that the .NET web control inheritance chain layers on functionality rather than forcing tons of implementation on the poor "end product" controls. I'd see if I can go with the flow on this. And this implies inheriting from the appropriate class to get the base upon which to build (pun intended).Looks like you want to build composite web controls. Read carefully the documentation on
System.Web.UI
namespace. Consider inheriting fromSystem.Web.UI.CompositeControl
. It gives you a child control collection and some built-in rendering. And it implementsINamingContainer
for managing child control unique IDs.Just a thought, maybe you can make a class that constructs custom composites at runtime (can you say
factory pattern
?). Read carefully the documentation onSystem.Web.UI
namespace Anyway, the base already knows how to render the composite. Each sub-control (textbox, listbox, etc) knows how to render itself. In the factory, each sub-control is given it's data binding. Then injects them into your custom CompositeControl constructor(s).一个建议:使 AssetDataInputControlBase 成为一个 Canvas 并在其中放置您想要的任何控件。作为一个画布,它的行为很像一个控件。您需要的任何特定于控制的方法/属性都需要向 ADICB 添加调用控制方法的方法。如果有很多,这个主意就不太好。
另一个建议:您的控件可以实现一个接口,该接口具有返回类似 AssetDataInputControlBase 之类的方法,仅在这种情况下 ADICB 不会实现 Control 或其他任何内容。相反,它只会有 AssetID、AssetStructureField 和 DataField(以及稍后需要的其他内容)。因此,您的控件(例如 AssetDataStringControl)只需扩展 Control(例如 TextBox),此外还包含对 ADICB 对象的引用。
这假设 ADICB 的值相当独立于控件(例如文本框)。如果 StructureField 的 get 方法需要来自 TextBox 的各种信息,并且需要以不同的方式获取它(如果是 ListBox),那么一切都会变得混乱,您需要更好的解决方案。如果不是,则您的控件只是 TextBox、ListBox 等的扩展,并添加了对 ADICB 对象的引用。一个 ADICB 类,无论多么复杂,一旦编写完毕就可以供所有控件使用。
这看起来确实是多重继承的一个很好的论据。
One suggestion: make AssetDataInputControlBase a Canvas and place any Control you want inside it. Being a canvas, it will behave a lot like a control. Any Control specific methods/properties you need would necessitate adding methods to ADICB that call the Control methods. If there's a lot of them, this idea isn't so good.
Another suggestion: Your controls could implement an interface that has a method that returns something like AssetDataInputControlBase, only in this case ADICB would not implement Control, or anything else. Instead, it would just have AssetID, AssetStructureField, and DataField (and other stuff as needed later). So your controls (such as AssetDataStringControl) just extend a Control (such as TextBox) and, in addition, contain a reference to to an ADICB object.
This assumes the ADICB's values are rather independent of the Control (TextBox, say). If StructureField's get method needs all kinds of information from the TextBox, and needs to get it in different ways is if is instead a ListBox, everything's going to get all tangled up and you need a better solution. If not, your controls are just extentions of TextBox, ListBox, etc., with one added reference to an ADICB object. One ADICB class, however complex, once written can be used by all your controls.
This does look like a good argument for multiple inheritance.