延迟扩展应用程序的所有控件,但很容易
Extend all controls of the application late, but easily
假设我的应用程序有大约 300 个不同形式的标准控件。
总有一天会发现给所有控件添加额外的成员会很好。
必须做什么?我的想法是:
从基数 class 中导出每种类型的 Control
,如下所示:
public partial class MyButton : Button, MyInterface
{
...
}
public partial class MyTextBox : TextBox, MyInterface
{
...
}
public interface MyInterface
{
// Additional members
...
}
这意味着触摸每一个 Control
以将其从
private System.Windows.Forms.Button myButton;
private System.Windows.Forms.TextBox myTextBox;
至
private MyButton myButton;
private MyTextBox myTextBox;
来自
this.myButton = new System.Windows.Forms.Button();
this.myTextBox = new System.Windows.Forms.TextBox();
至
this.myButton = new MyButton();
this.myTextBox = new MyTextBox();
我的问题:有没有更简单的方法?也许,如果可能的话,用另外派生自 MyInterface
的 class 蜜蜂替换 Control
class? (Control.Tag
属性 没有选项)
我不会做的。控件的正常工作没有变化,只是想存储一些额外的信息?我会使用全局词典,其中 MyExtension class 包含将添加到您的 MyInterface 中的所有成员。
如果你只想添加方法,你可以简单地使用扩展方法。
否则我会建议您创建接口来定义 general/specific 行为,抽象 classes 用于这些接口的通用实现(继承 classic 控件),最后使您的 classes 继承自这些抽象 classes。但是正如您提到的那样,您将不得不重命名它。
(你可以想象使用命名空间的技巧来避免更改名称或动态添加成员到 class,但我不建议这样做)。
创建扩展程序提供程序对您来说似乎是个不错的选择。 A ToolTip
是一个例子;当您向表单添加 ToolTip
时,它会向所有控件添加 ToolTip on ToolTip1
字符串 属性。
扩展程序提供程序向其他组件提供属性。您可以设计您的扩展器组件,将一些具有不同(简单或复杂)类型的属性添加到不同的控件类型。扩展程序提供程序提供的 属性 实际上驻留在扩展程序提供程序对象本身中,因此不是它修改的组件的真实 属性。在设计时,属性 出现在属性 window 中。在运行时,你可以在扩展器组件上调用getter和setter方法。
资源
例子
这是一个非常简单的示例组件,它将字符串 SomeProperty
属性 添加到 TextBox
和 Button
。 属性 是一个简单的,没有实际用途,但它是您的起点:
using System.Collections;
using System.ComponentModel;
using System.Windows.Forms;
[ProvideProperty("SomeProperty", typeof(Control))]
public class ControlExtender : Component, IExtenderProvider
{
private Hashtable somePropertyValues = new Hashtable();
public bool CanExtend(object extendee)
{
return (extendee is TextBox ||
extendee is Button);
}
public string GetSomeProperty(Control control)
{
if (somePropertyValues.ContainsKey(control))
return (string)somePropertyValues[control];
return null;
}
public void SetSomeProperty(Control control, string value)
{
if (string.IsNullOrEmpty(value))
somePropertyValues.Remove(control);
else
somePropertyValues[control] = value;
}
}
假设我的应用程序有大约 300 个不同形式的标准控件。 总有一天会发现给所有控件添加额外的成员会很好。
必须做什么?我的想法是:
从基数 class 中导出每种类型的 Control
,如下所示:
public partial class MyButton : Button, MyInterface
{
...
}
public partial class MyTextBox : TextBox, MyInterface
{
...
}
public interface MyInterface
{
// Additional members
...
}
这意味着触摸每一个 Control
以将其从
private System.Windows.Forms.Button myButton;
private System.Windows.Forms.TextBox myTextBox;
至
private MyButton myButton;
private MyTextBox myTextBox;
来自
this.myButton = new System.Windows.Forms.Button();
this.myTextBox = new System.Windows.Forms.TextBox();
至
this.myButton = new MyButton();
this.myTextBox = new MyTextBox();
我的问题:有没有更简单的方法?也许,如果可能的话,用另外派生自 MyInterface
的 class 蜜蜂替换 Control
class? (Control.Tag
属性 没有选项)
我不会做的。控件的正常工作没有变化,只是想存储一些额外的信息?我会使用全局词典,其中 MyExtension class 包含将添加到您的 MyInterface 中的所有成员。
如果你只想添加方法,你可以简单地使用扩展方法。
否则我会建议您创建接口来定义 general/specific 行为,抽象 classes 用于这些接口的通用实现(继承 classic 控件),最后使您的 classes 继承自这些抽象 classes。但是正如您提到的那样,您将不得不重命名它。 (你可以想象使用命名空间的技巧来避免更改名称或动态添加成员到 class,但我不建议这样做)。
创建扩展程序提供程序对您来说似乎是个不错的选择。 A ToolTip
是一个例子;当您向表单添加 ToolTip
时,它会向所有控件添加 ToolTip on ToolTip1
字符串 属性。
扩展程序提供程序向其他组件提供属性。您可以设计您的扩展器组件,将一些具有不同(简单或复杂)类型的属性添加到不同的控件类型。扩展程序提供程序提供的 属性 实际上驻留在扩展程序提供程序对象本身中,因此不是它修改的组件的真实 属性。在设计时,属性 出现在属性 window 中。在运行时,你可以在扩展器组件上调用getter和setter方法。
资源
例子
这是一个非常简单的示例组件,它将字符串 SomeProperty
属性 添加到 TextBox
和 Button
。 属性 是一个简单的,没有实际用途,但它是您的起点:
using System.Collections;
using System.ComponentModel;
using System.Windows.Forms;
[ProvideProperty("SomeProperty", typeof(Control))]
public class ControlExtender : Component, IExtenderProvider
{
private Hashtable somePropertyValues = new Hashtable();
public bool CanExtend(object extendee)
{
return (extendee is TextBox ||
extendee is Button);
}
public string GetSomeProperty(Control control)
{
if (somePropertyValues.ContainsKey(control))
return (string)somePropertyValues[control];
return null;
}
public void SetSomeProperty(Control control, string value)
{
if (string.IsNullOrEmpty(value))
somePropertyValues.Remove(control);
else
somePropertyValues[control] = value;
}
}