2009-06-12 48 views
3

我需要以下問題的幫助:如何創建一個屬性來存儲另一個屬性中所選值的索引?

我有一個有兩個屬性的類。

private byte m_selectedValue; 
public byte SelectedValue 
{ 
    get { return m_selectedValue; } 
    set { m_selectedValue = value; } 
} 

private string[] m_possibleValues; 
public string[] PossibleValues 
{ 
    get { return m_possibleValues; } 
    set { m_possibleValues = value; } 
} 

PossibleValues存儲可選值的列表。 SelectedValue包含實際選定值的索引。

在此狀態下,屬性編輯器顯示所選值的索引。我想在屬性網格中使用組合框選擇值,這與Enum屬性使用的樣式相同。組合框的列表將從PossibleValues屬性填充。

在這篇文章的幫助下(http://www.codeproject.com/KB/cpp/UniversalDropdownEditor.aspx)我設法創建了一個自定義編輯器,用屬性PossibleValues顯示屬性網格上的組合框。我也可以選擇該值,但屬性網格仍顯示值的索引而不是值本身。

這是編輯器的修改的源(原來是從CodeProject):

public class EnumParamValuesEditor : UITypeEditor 
{ 
    private IWindowsFormsEditorService edSvc; 

    public override UITypeEditorEditStyle GetEditStyle(System.ComponentModel.ITypeDescriptorContext context) 
    { 
     if ((context != null) && (context.Instance != null)) 
      return UITypeEditorEditStyle.DropDown; 
     return UITypeEditorEditStyle.None; 
    } 

    public override object EditValue(System.ComponentModel.ITypeDescriptorContext context, IServiceProvider provider, object value) 
    { 
     if ((context == null) || (provider == null) || (context.Instance == null)) 
      return base.EditValue(provider, value); 
     edSvc = (IWindowsFormsEditorService)provider.GetService(typeof(IWindowsFormsEditorService)); 
     if (edSvc == null) 
      return base.EditValue(provider, value); 
     ListBox lst = new ListBox(); 
     PrepareListBox(lst, context); 
     lst.SelectedIndex = (byte)value; 
     edSvc.DropDownControl(lst); 
     if (lst.SelectedItem == null) 
      value = null; 
     else 
      value = (byte)lst.SelectedIndex; 
     return value; 
    } 

    private void PrepareListBox(ListBox lst, ITypeDescriptorContext context) 
    { 
     lst.IntegralHeight = true; 
     string[] coll = ((EnumTerminalParam)context.Instance).PossibleValues; 
     if (lst.ItemHeight > 0) 
     { 
      if ((coll != null) && (lst.Height/lst.ItemHeight < coll.Length)) 
      { 
       int adjHei = coll.Length * lst.ItemHeight; 
       if (adjHei > 200) 
        adjHei = 200; 
       lst.Height = adjHei; 
      } 
     } 
     else 
      lst.Height = 200; 
     lst.Sorted = true; 
     FillListBoxFromCollection(lst, coll); 
     lst.SelectedIndexChanged += new EventHandler(lst_SelectedIndexChanged); 
    } 

    void lst_SelectedIndexChanged(object sender, EventArgs e) 
    { 
     if (edSvc == null) 
      return; 
     edSvc.CloseDropDown(); 
    } 

    public void FillListBoxFromCollection(ListBox lb, ICollection coll) 
    { 
     lb.BeginUpdate(); 
     lb.Items.Clear(); 
     foreach (object item in coll) 
      lb.Items.Add(item); 
     lb.EndUpdate(); 
     lb.Invalidate(); 
    } 

} 

當然,這需要進一步的修改,以正確地處理某些情況下(例如在PossibleValues是空的)。

那麼有可能在屬性編輯器中顯示PossibleValues [SelectedValue]而不是SelectedValue?

回答

1

您需要將自定義的TypeConverter附加到您的SelectedValue屬性,並使PossibleValues不可瀏覽。 TypeConverter將負責在PropertyGrid中顯示字符串而不是ints。所以基本上,你需要重寫CanConvertFrom,CanConvertTo,ConvertFrom和ConvertTo。當你想獲得你的自定義字符串時,使用傳遞給這些方法的context參數並在你的目標實例中調用你的PossibleValues屬性。這應該可以做到。看起來你不需要任何自定義的UITypeEditor。

+0

我認爲GetStandardValuesSupported和GetStandardValues用於在屬性編輯器中顯示組合框。不幸的是,GetStandardValues必須返回一個與屬性本身屬於同一類型元素的集合,至少根據http://msdn.microsoft.com/en-us/library/ayybcxe5.aspx。我如何使屬性編輯器顯示與ConvertFrom或ConvertTo方法的組合框? – starobrno 2009-06-15 14:40:23

0

而不是兩個單獨的屬性,爲什麼不把它們綁定在一個Dictionary類型中。在這種情況下更容易使用。以索引作爲關鍵字並將字符串[]作爲值。只是不要將自己限制爲索引的一個字節。

+0

如果我將字符串[]中的PossibleValues更改爲字典,我仍然需要一個屬性來存儲當前選定的值。應用程序處理來自外部設備的信息,並在處理完信息後發回。我使用字節數據類型,因爲此設備只接受從0到255的值。 – starobrno 2009-06-12 10:11:53

相關問題