[英]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.