2012-02-21 26 views
2

語境提示Winforms中

屬性我有一個非常大量的小的類或結構的。這些類的實現細節並不重要,但對於每個類都會有一些我想公開的簡單的內置數據類型屬性,以便它們可以在WinForms控件中進行編輯。儘管如此,這些將會不同班級完全不同。例如:

class SleepAction : IGameAction 
{ 
    public float Duration { get; set; } 
} 

class TeleportCharacterAction : IGameAction 
{ 
    public string CharacterId { get; set; 
    public string DestinationRoomId { get; set; } 
    public Vector2 DestinationPosition { get; set; } 
} 

的問題是,我想有一個的WinForms控制,它能夠編輯對象類型的所有的。上面會有一個所有類類型的下拉列表,當從這個下拉列表中選擇一個項目時,接口將會改變以適應該類型的屬性,並創建一個該類型的實例來存儲數據。

起初我考慮手工製作這些接口的每個,可能使用一個TabControl對象,每一個類標籤上,與突出部隱藏。但是隨後類的數量呈指數級增長,所以我正在轉向其他解決方案,可能會使用屬性和反思。我只是不確定如何開始。

我心目中現在是一樣的東西:

class ActionEditorControl : UserControl 
{ 
    void ChangeEditorMode(Type type) 
    { 
     // Clear all GUI interface 
     // Create object of type Type with default constructor 
     // Use Type metadata to generate new GUI interface 
     // Databind new interface to object properties 
    } 

    object GetObject() 
    { 
     // Return current object 
    } 
} 

而且在我的模型對象,我可以使用屬性添加必要的元數據:

class SleepAction : IGameAction 
{ 
    [FieldLabel("Duration")] 
    [FieldType("NumericSpinner")] 
    public float Duration { get; set; } 
} 

class TeleportCharacterAction : IGameAction 
{ 
    [FieldLabel("Character")] 
    [FieldType("CharacterList")] 
    public string CharacterId { get; set; 

    [FieldLabel("Room")] 
    [FieldType("RoomList")] 
    public string DestinationRoomId { get; set; } 

    [FieldLabel("Position")] 
    [FieldType("VectorPicker")] 
    public Vector2 DestinationPosition { get; set; } 
} 

當然我需要給教我的控制如何解釋這些屬性。現在我的實際問題。

具體問題

  1. 將這項工作?
  2. 有沒有解決這個問題我俯瞰一個更好的選擇?
  3. 如何處理在界面上放置或控件的佈局?
  4. 最後,我從未使用過自定義屬性。任何讓我開始的好例子?

回答

2

是的,這應該工作,我已經建立,用於基於實體動態搜索對話框類似的東西。

自定義屬性,可以識別應該出現在窗體上的屬性。然後,表單可以爲這些屬性生成控件,並使用數據綁定將控件鏈接回對象上的屬性。

一個TableLayoutPanel可以與生成控件的佈局有所幫助。一列可以存儲標籤對象,第二列可以存儲控件(文本框等)。或者如果你想要更多的專欄,可以選擇幾套。

與屬性

既然你有一個類型,你可以搜索每個屬性爲您的特殊屬性的工作:

foreach (var property in searchObjectType.GetProperties()) 
{ 
    var labelAttrib = (FieldLabelAttribute)property.GetCustomAttributes(typeof(FieldLabelAttribute), false).FirstOrDefault(); 
    var typeAttrib = (FieldTypeAttribute)property.GetCustomAttributes(typeof(FieldTypeAttribute), false).FirstOrDefault(); 
} 

表面板:

一旦你知道你需要要建立一個控制,找出你要建立什麼樣的控制:(這假設你有一個屬性與訂單屬性,所以你知道'在哪裏'將控件放置在網格中。這個例子是基於五列,是標籤,控制,隔離,標籤,控制):

if (type == typeof(string)) 
{ 
    generatedControl = new Textbox(); 
    generatedControl.DataBindings.Add("Text", myObject, property.Name); 
} 

然後將該控件添加到表(假設您創建了一個標籤控件):

pnlLayout.Controls.Add(label, (myAttrib.Order % 2 * 3), myAttrib.Order/2); 

pnlLayout.Controls.Add(generatedControl, (myAttrib.Order % 2 * 3) + 1, myAttrib.Order/2); 
+0

謝謝,你釘了它!事實上,看起來非常簡單,我期待它變得更加複雜。 – 2012-02-22 00:27:36

1

你所描述的聽起來很像PropertyGrid

+0

這是一個很好的觀點,並且我意識到我可能會在我的問題中留下一些信息。我曾考慮過首先使用屬性網格,但我真正想要的是使用一般計算機用戶比較熟悉的外觀,如帶有標籤/文本框/列表/大型控件的表單。屬性網格具有「程序員」的感覺,並且我想在這種情況下避免使用整體濃縮的外觀。 – 2012-02-21 23:53:02

+0

夠公平的。在這種情況下,quip的答案看起來不錯。您也許應該提供一種機制,允許您在需要時插入定製的用戶界面。我將定義一個由用戶控件實現的IEditor接口,該接口基於屬性生成ui,也可以通過特定於類的用戶控件來實現。工廠可以構建正確的實現。 – 2012-02-22 02:56:46

相關問題