編寫與.NET屬性視窗互動的RAD組件(四)

來源:互聯網
上載者:User
互動 七、 編寫和顯示訂製的類型
屬性視窗中的編輯有如下三種工作方式:一,有些場合可以作為字串來編輯,然後由TypeConverter來實作類別型的轉換。二,可以顯示一個下拉式清單來選擇值。三,一個省略按鈕提供其他的UI介面來編輯值,比如FileDialog和FontPicker。我們已經講過了字串形式,接著我們就來看下拉式清單。

.NET framework已經包含了好幾種下拉式清單的例子,如Color,AccessibleRole,Dock等屬性。我們從下圖可以看到下拉式清單的具體實現。




圖4. 下拉式清單編輯器

實現下拉的工作同樣是由TypeConverter來定義。如果看TypeConverter的說明,可以看到有三個虛函數來實現這個功能:GetStandardValuesSupported(),GetStandardValues()和GetStandardValuesExclusive()。重載這些方法,我們可以為屬性提供預先定義好的值列表。實際上,是TypeConverter實現了下拉式清單中的枚舉值。屬性視窗自己本身並沒有代碼來處理這種下拉式清單的編輯,而僅僅是使用TypeConverter的方法。

舉個例來說,我們有一個包含Relation屬性的FamilyMember組件,允許使用者選擇與其他人之間的關係。如果要使設計時介面更友好的話,屬性視窗應該使用下拉式清單來提供一些常用值的選擇:如mother,father,daughter和sister等。除了提供的常用值之外,組件使用者也可以輸入其他的表示關係的字串值。

public class FamilyMember : Component

{

private string relation = "Unknown";

[TypeConverter(typeof(RelationConverter)),Category("Details")]

public string Relation

{

get { return relation;}

set { this.relation = value;}

}

}





internal class RelationConverter : StringConverter

{

private static StandardValuesCollection defaultRelations =

new StandardValuesCollection(

new string[]{"Mother", "Father", "Sister",

"Brother", "Daughter", "Son",

"Aunt", "Uncle", "Cousin"});





public override bool GetStandardValuesSupported(

ITypeDescriptorContext context)

{

return true;

}





public override bool GetStandardValuesExclusive(

ITypeDescriptorContext context)

{

// returning false here means the property will

// have a drop down and a value that can be manually

// entered.

return false;

}





public override StandardValuesCollection GetStandardValues(

ITypeDescriptorContext context)

{

return defaultRelations;

}

}

不過如何做一個更加定製化的UI呢?我們可以使用UITypeEditor類。UITypeEditor類包括了在顯示內容或者是編輯屬性(比如下拉式清單和省略按鈕)時可以由屬性視窗調用的方法。

一些類似於Image,Color,Font.Name的屬性類型會在屬性值的左邊有一個小的圖形化表示,這是通過重載UITypeEditor的PaintValue方法實現的。當屬性視窗得到定義了編輯器的屬性值的時候,它就提供給編輯器一個矩形框對象(Rectangle)和畫圖的對象(Graphic),他們都包含在PaintValue方法的事件參數PaintValueEventArgs中。舉個例子來說,我們有一個Grade類需要有圖形化的表示。下面就是我們的Grade類。

[Editor(typeof(GradeEditor), typeof(System.Drawing.Design.UITypeEditor))]

[TypeConverter(typeof(GradeConverter))]

public struct Grade

{

private int grade;



public Grade(int grade)

{

this.grade = grade;

}





public int Value

{

get

{

return grade;

}

}

}

當我們輸入一個年齡的時候,我們可以看到左邊的一個圖形表示。




圖5. 輸入年齡





實現它並不困難。注意到賦給Grade類的EditorAttribute特性,它就是下面的這個類:

public class GradeEditor : UITypeEditor

{

public override bool GetPaintValueSupported(

ITypeDescriptorContext context)

{

// let the property browser know we'd like

// to do custom painting.

return true;

}





public override void PaintValue(PaintValueEventArgs pe)

{

// choose the right bitmap based on the value

string bmpName = null;

Grade g = (Grade)pe.Value;

if (g.Value > 80)

{

bmpName = "best.bmp";

}

else if (g.Value > 60)

{

bmpName = "ok.bmp";

}

else

{

bmpName = "bad.bmp";

}





// draw that bitmap onto the surface provided.

Bitmap b = new Bitmap(typeof(GradeEditor), bmpName);

pe.Graphics.DrawImage(b, pe.Bounds);

b.Dispose();

}

}

像我們上面提到的,UITypeEditor可以實現屬性的下拉選擇和彈出對話方塊選擇。後面的例子會包括這樣的代碼。如果想知道進一步的資訊的話,就要參考UITypeEditor.GetEditStyle和UITypeEditor.EditValue方法以及IWindowsFormsEditorService介面。

-----------------------------------

<<<<<<<<<<<<待續>>>>>>>>>>>>



相關文章

E-Commerce Solutions

Leverage the same tools powering the Alibaba Ecosystem

Learn more >

Apsara Conference 2019

The Rise of Data Intelligence, September 25th - 27th, Hangzhou, China

Learn more >

Alibaba Cloud Free Trial

Learn and experience the power of Alibaba Cloud with a free trial worth $300-1200 USD

Learn more >

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。