在建立自訂使用者控制項時,常需要將繼承自UserControl的屬性與事件隱藏,只開放想公開的部分,這裡將示範如何實現此想法。
這邊以MSDN中小時鐘為範例來示範:
1. 新增專案 >> Windows Form 控制項程式庫 >> 名稱:ctrlClockLib。
2. 將 UserControl1命名為 ctrlClock,設定 Size 為 250, 50,設定 BackColor 為 Black,並在其上放置 Label 元件,命名為 lblDisplay,設定 Size 為 240, 40,設定 Location 為 5, 5,並調整,設定 BackColor 為 DimGray,ForeColor 為 Lime,TextAlign 為 MiddleCenter,設定自己喜歡的字型與樣式。
3. 因為我們的重點不再建立 Clock 控制項,所以功能面的部份就不再這裡多作闡述,就以目前的樣子作為範例即可,按下【F6】建置方案,完成後接下來就要測試這個 Clock 控制項囉。
4. 首先,因為控制項不是獨立的應用程式,必須裝載在容器中才能測試,所以我們必須建立一個 Window Form 應用程式來做測試。
5. 按下【檔案】>>【加入】>>【新增專案】>>選擇【Windows Form 應用程式】>>為專案名稱命名為【Test】。
6. 【方案總管】>>【Test】專案 >>【參考】>> 按下滑鼠右鍵選擇【加入參考】。
7. 【方案】>>【專案】>> 勾選【ctrlClockLib】>>【確定】。
8. 【工具箱】>>【ctrlColckLib 元件】>>【ctrlClock】>>點擊滑鼠兩下,將 Clock 控制項增加到剛剛建立的 Windows Form 上。
9. 點擊剛加入的 Clock 控制項,開啟【屬性】檢視視窗,可發現 UserControl 的所有公開屬性皆繼承並顯示出來了。
10. 好了,開始進入重點了,此元件並不須要讓使用者作耴此多的設定,所以我們要將不需要的項目隱藏。
11. ctrlClock 控制項的程式碼應該如下所示:
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Drawing;
using System.Data;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
namespace ctrlClock
{
public partial class ctlClock: UserControl
{
public ctlClock()
{
InitializeComponent();
}
}
}
12. 於【ctrlClockLib】專案名稱上,點擊滑鼠右鍵,選擇【加入】>>【新增項目】。
13. 選擇【類別】>>>命名為【ctrlClockDesigner.cs】>>【新增】。
14. 將 System.Desigm.dll 加入參考。
15. 為新增的 ctrlClockDesigner 類別加入下方程式碼。
using System;
using System.Linq;
using System.Windows.Forms.Design;
namespace ComponentSet
{
/// <summary>
/// 提供CustomUserControl在Design-Time過濾屬性以及事件的類別
/// </summary>
[System.Security.Permissions.PermissionSet(System.Security.Permissions.SecurityAction.Demand, Name = "FullTrust")]
public class JLabelExDesigner : ParentControlDesigner
{
/// <summary>
/// 設定要過濾掉的的屬性
/// </summary>
static String[] DisabledProperty = new string[]
{
"AccessibleDescription", "AccessibleName", "AccessibleRole",
"AllowDrop", "Anchor", "AutoScroll", "AutoScrollMargin", "AutoScrollMinSize",
"AutoSize", "AutoSizeMode", "AutoValidate", "BackColor", "BackgroundImage",
"BackgroundImageLayout", "BorderStyle", "CausesValidation", "ContextMenuStrip",
"Cursor", "Dock", "Enabled", "ForeColor", "ImeMode",
"Margin", "MaximumSize", "MinimumSize", "Padding", "RightToLeft",
"TabIndex", "TabStop", "Tag", "UseWaitCursor", "Visible"
};
/// <summary>
/// 過濾屬性
/// </summary>
/// <param name="properties"></param>
protected override void PreFilterProperties(System.Collections.IDictionary properties)
{
//針對UserControl每個屬性進行過濾
foreach (var pi in typeof(System.Windows.Forms.UserControl).GetProperties())
{
if (properties.Contains(pi.Name))
{
if (DisabledProperty.Contains(pi.Name))
{
properties.Remove(pi.Name);
}
}
}
base.PreFilterProperties(properties);
}
protected override void PreFilterEvents(System.Collections.IDictionary events)
{
//針對UserControl每個事件進行過濾
foreach (var ei in typeof(System.Windows.Forms.UserControl).GetEvents())
{
if (events.Contains(ei.Name))
events.Remove(ei.Name);
}
base.PreFilterEvents(events);
}
}
}
16. 在回到 ctrlClock 控制項的程式碼,於 class 的上方增加一行 [Designer(typeof(ctrlClockDesigner))],程式碼如下所示:
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Drawing;
using System.Data;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
namespace ctrlClock
{
[Designer(typeof(ctrlClockDesigner))] //設定那些屬性要在子類別中顯示
public partial class ctlClock: UserControl
{
public ctlClock()
{
InitializeComponent();
}
}
}
17. 在回到 Windows Form 中來看一下 ctrlClock 控制項,點擊一下控制項並開啟屬性檢視視窗,是否變成如下圖所示了呢?如果是,恭喜你成功了~~~ 落落長的屬性列表不見囉~~