UITypeEdit“我要紅桃”
假如,你現在在做一個“撲克”控制項,撲克牌有個屬性--花色,你想在使用者選擇花色這個屬性後,屬性視窗呈現的不僅僅是文字,還有一個小小的花色表徵圖來表示花色,“紅桃”就有個小“紅桃”表徵圖在前面顯示,“黑桃”就有個“黑桃”表徵圖在前面顯示,就像你選擇其它控制項的BackColor時,顏色前還有個小方色塊來表示選定的顏色,多體貼人的設計啊。
現在,我們就來做這件事:
public class Squeezer
{
.
public CardTypes CardType
{
}
}
[Editor(typeof(CardTypesEditor), typeof(System.Drawing.Design.UITypeEditor))]
public class CardTypes
{
..
}
public class CardTypesEditor : UITypeEditor
{
public override bool GetPaintValueSupported(ITypeDescriptorContext context)
{
return true;//支援畫小圖
}
public override void PaintValue(PaintValueEventArgs pe) //定義根據值畫小圖的邏輯
{
string bmpName = null;
CardTypes C = (CardTyes)pe.Value;
switch(C.Value)
{
case CarderTypes.HongTao:
bmpName = "紅桃.bmp";//圖片必須是內嵌資源,大小為16*16,類型為BMP
break;
}
Bitmap b = new Bitmap(typeof(GradeEditor), bmpName);
pe.Graphics.DrawImage(b, pe.Bounds);
b.Dispose();
}
}
在上面的代碼中,我們通過EditorAttribute來使花色類和一個Editor關聯,再通過這個Editor來實現畫示意小圖的功能。
好了,現在你的創造力可能又在鼓動你思考一個新問題了,我不想讓讓使用者僅僅通過一個簡單的只呈現值的下拉式清單(通過EnumConverter實現的)來選擇屬性的值,我想實現像BackColor、Dock這樣的非常友善的互動給使用者使用,好吧,我們來進入下一步。
首先我們要製做一個合適的小視窗(CardTypesEditorControl)來定製互動時的介面,這個表單繼承自System.Window.Forms.UserControl或System.Window.Forms.From,總之它就是一個WinFrom表單,這個表單怎麼做,我這裡就不展開論述了,只是你要在這個表單類中彙總(不是組合,這裡是引用,由Editor傳過來)一個IWindowsFormsEditorService,已便更好的互動,並且,能控制項何時關閉開啟的這個下列式的視窗,比如說在滑鼠按鍵的Up事件中edSvc.CloseDropDown(),這樣使用者點擊滑鼠進行了選擇之後就能關閉表單,傳回值。
好,我們來看我們的Editor怎麼擴充:
CardTypes target;
CardTypesEditorControl ui;
public CardTypesUIEditor(CardTypes target)
{
this.target = target;
}
//通過Editor能到使用者操作的值的邏輯實現
public override object EditValue(ITypeDescriptorContext context, IServiceProvider sp, object value)
{
// 得到IDE的互動服務
IWindowsFormsEditorService edSvc = (IWindowsFormsEditorService)sp.GetService(typeof(IWindowsFormsEditorService));
if (edSvc == null)
{
return value;
}
if (ui == null)
{
ui = new CardTypesEditorControl();//建立屬性操作表單執行個體
}
ui.SelectedCardTypes = (CardTypes)value;//原始值,SelectedCardTypes屬性只是一個例子,你可以用任意實現自己的邏輯。
ui.EditorService = edSvc;//傳服務過去,見代碼上面的說明
ui.Target = (CardTypes)context.Instance;//得到連線物件的執行個體
edSvc.DropDownControl(ui);//把表單顯示為一個下接式表單,可選的值還有edSvc.ShowDialog(ui),
//這樣的話以一個彈出表單的形式顯示表單,也許你更喜歡這種方式。
return ui.SelectedCardTypes;//我們在表單邏輯中更改SelectedCardTypes值,在操作表單關閉時得到這個值。
}
//視窗出現樣式,可選值還有Modal,在屬性後出出現一個省略符號,點擊彈出模式表單或有視窗的對話方塊,就像CollectionEditor,
//None,不出現任何操UI,老老實實填值
public override System.Drawing.Design.UITypeEditorEditStyle GetEditStyle(ITypeDescriptorContext context)
{
return System.Drawing.Design.UITypeEditorEditStyle.DropDown;
}
呵呵,是不是現在有得花樣給你玩了?
在EditValue方法中用一句return UrlBuilder.BuildUrl( (IComponent) context.Instance, null, (string) value, Caption, Filter,Options)你就可以做出一個URL編輯器;用ColorEditor.ColorUI colorUI = new ColorEditor.ColorUI(this);colorUI.Start(edSvc, value);edSvc.DropDownControl(colorUI);這樣的幾句話就能實現一個顏色選擇互動介面。(注意代碼沒有處理null等異常情況)