[英]How to remove the Multiline property in custom TextBox control?
我在winforms中创建一个自定义TextBox控件,不需要多行选项。
[Browsable(flase)]
我实现了从属性组隐藏Multiline属性。 但是,仍然可以从代码中进行更改。 有没有办法完全删除此属性? 从类继承时,不应删除父级的功能。 任何人都应该能够使用您的班级代替父班级(这被称为Liskov替代原理)。
听起来您想制作一个承载 TextBox
控件。 这使您可以完全控制公开的属性,并且不会违反TextBox
类的协定。
设计器中显示带有“多行选项”复选框的下拉菜单的箭头按钮称为SmartTag。
为了加快开发速度,许多控件都提供了智能标记,这些标记是上下文相关的菜单,可让您在设计时以单个手势执行诸如此类的常见任务。 这些任务称为智能标记动词。
TextBox
SmartTag是根据其设计器(System.Windows.Forms.Design.TextBoxDesigner)公开的属性生成的; 特别是它从其祖先ComponentDesigner继承的ActionLists属性 。 ActionLists是DesignerActionList对象的集合。
您可以创建一个未定义SmartTag的自定义控件设计器,然后将其分配为自定义控件的设计器。 但是,这将要求您重新实现TextBoxDesigner的所有功能,以提供预期的设计体验,因为TextBoxDesigner是一个内部类,无法继承。 一种更简单的方法是挂接到可用的设计器服务并获得对默认TextBoxDesigner的引用。 这是通过覆盖控件的Site Property来完成的 。
// add project assembly reference: System.Design
using System.Windows.Forms;
using System.ComponentModel;
using System.ComponentModel.Design;
using System;
using System.Windows.Forms.Design;
public class SingleLineTB : TextBox
{
[EditorBrowsable(EditorBrowsableState.Never), Browsable(false)]
public override bool Multiline
{
get {return base.Multiline;}
set {}
}
#region Designer Services
private IDesignerHost designerHost;
public override ISite Site
{
get {return base.Site;}
set
{
base.Site = value;
if (value == null)
{
// this instance is being removed from the design surface
DetachDesignerServices();
}
else // being added to the design surface
{
designerHost = (IDesignerHost)value.GetService(typeof(IDesignerHost));
if (designerHost != null)
{
if (designerHost.Loading)
{
// the designer has not finished loading,
// postpone all other connections until it has finished loading
designerHost.LoadComplete += DesignerHostLoaded;
}
else
{
if (designerHost.InTransaction)
{
// designerHost loaded, but is in the in the process of creating this instance
designerHost.TransactionClosed += DesignerTransactionClosed;
}
else
{
// this will probably never be hit as the designer
// should be siting the component in a transaction
ClearDesignerActionLists();
}
}
}
}
}
}
private void DesignerHostLoaded(object sender, EventArgs e)
{
designerHost.LoadComplete -= DesignerHostLoaded;
ClearDesignerActionLists();
}
private void DesignerTransactionClosed(object sender, DesignerTransactionCloseEventArgs e)
{
designerHost.TransactionClosed -= DesignerTransactionClosed;
ClearDesignerActionLists();
}
private void DetachDesignerServices()
{
if (designerHost != null)
{
designerHost.TransactionClosed -= DesignerTransactionClosed;
designerHost.LoadComplete -= DesignerHostLoaded;
designerHost = null;
}
}
private void ClearDesignerActionLists()
{
ControlDesigner myDesigner = designerHost.GetDesigner(this) as ControlDesigner;
myDesigner?.ActionLists.Clear();
}
#endregion // "Designer Services
}
该代码首先获取对设计器主机的引用,并使用该引用获取对控件设计器的引用。 一旦获得设计者参考,便可以清除ActionLists
集合以防止生成SmartTag。
不能完全继承 MultiLine属性是您第二个请求的功能,因为您不能取消继承该属性。 您能做的最好的事情就是尽可能地将其隐藏在代码编辑器中。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.