2016-12-26 42 views
2

比方說,我有幾個單選按鈕和一些自定義對象作爲數據源。Windows窗體RadioButton列表 - 綁定Enum屬性到RadioButton

作爲例子

public enum SomeModeType 
{ 
    firstMode = 10, 
    secondMode = 20, 
    thirdMode = 30 
} 

public class MyCustomObject:INotifyPropertyChanged 
{ 

    private SomeModeType _mode; 
    public SomeModeType Mode 
    { 
     set { _mode = value; } 
     get { return _mode; } 
    } 

    public event PropertyChangedEventHandler PropertyChanged; 

    protected virtual void OnPropertyChanged(string propertyName) 
    { 
     var handler = PropertyChanged; 
     if (handler != null) 
     { 
      handler(this, new PropertyChangedEventArgs(propertyName)); 
     } 
    } 
} 

如何此對象屬性的東西,如綁定(如果可能)3個不同的單選按鈕:

如果radiobuttonOne檢查 - 對象屬性mode套到firstMode

如果檢查radiobuttonTwo - 對象屬性mode設置爲secondMode

如果radiobuttonThree檢查 - 對象屬性mode套到thirdMode

等等等等

或其更好地使用這個事件?

P.S. 我知道如何使用活動,但它不知所措,通過像rb1chnagedrb2changed,...,rb100changed這樣的事件創建活動,不是嗎?

P.P.S.

MerryXmas!

+0

當你在聲明枚舉類型,它只是一個條目。你需要一個集合來綁定到單選按鈕列表。嘗試聲明'List '作爲屬性,並填寫每個枚舉的成員 –

+0

@AnupSharma,但如何幫助? 我的意思是,爲什麼不直接綁定單選按鈕就好像 - 如果選擇1st,則字段值將變爲firstMode,如果是2nd,則將字段值重寫爲secondMode – DanilGholtsman

+0

我共享一個RadioButtonList控件[here] (http://stackoverflow.com/a/41355419/3110834)。 –

回答

1

對於枚舉的每個值,您需要創建一個RadioButton並將其Checked值綁定到數據源的Mode屬性。那麼您需要使用FormatParse事件BindingMode值轉換爲Checked屬性的合適值,反之亦然。

實施例 - 單選按鈕列表使用FlowLayoutPanel的

例如把一個FlowLayoutPanel控制窗體上,然後在Load事件Form寫的以下代碼。該代碼將動態添加RadioButton控制到流佈局面板,並執行數據綁定:

var enumValues = Enum.GetValues(typeof(SomeModeType)).Cast<object>() 
    .Select(x => new { Value = x, Name = x.ToString() }).ToList(); 
enumValues.ForEach(x => 
{ 
    var radio = new RadioButton() { Text = x.Name, Tag = x.Value }; 
    var binding = radio.DataBindings.Add("Checked", dataSource, 
     "Mode", true, DataSourceUpdateMode.OnPropertyChanged); 
    binding.Format += (obj, ea) => 
    { ea.Value = ((Binding)obj).Control.Tag.Equals(ea.Value); }; 
    binding.Parse += (obj, ea) => 
    { if ((bool)ea.Value == true) ea.Value = ((Binding)obj).Control.Tag; }; 
    flowLayoutPanel1.Controls.Add(radio); 
}); 

在上面的例子中,dataSource可以是MyCustomObjectBindingList<MyCustomObject>或含有在其DataSource一個List<MyCustomObject>一個BindingSource。使用重繪列表框

作爲另一個選項,您可以使用一個所有者繪製ListBox和項目呈現RadioButton單選按鈕列表 -

另一種選擇。這樣,您可以將SelectedValueListBox綁定到您的對象的Mode屬性。以下代碼中的dataSourcs可以像上面的例子。穿上形式ListBox寫下面的代碼Load活動形式:

var enumValues = Enum.GetValues(typeof(SomeModeType)).Cast<object>() 
    .Select(x => new { Value = x, Name = x.ToString() }).ToList(); 
this.listBox1.DataSource = enumValues; 
this.listBox1.ValueMember = "Value"; 
this.listBox1.DisplayMember = "Name"; 
this.listBox1.DataBindings.Add("SelectedValue", dataSource, 
     "Mode", true, DataSourceUpdateMode.OnPropertyChanged); 
this.listBox1.DrawMode = DrawMode.OwnerDrawFixed; 
this.listBox1.ItemHeight = RadioButtonRenderer.GetGlyphSize(
    Graphics.FromHwnd(IntPtr.Zero), 
      RadioButtonState.CheckedNormal).Height + 4; 
this.listBox1.DrawItem += (obj, ea) => 
{ 
    var lb = (ListBox)obj; 
    ea.DrawBackground(); 
    var text = lb.GetItemText(lb.Items[ea.Index]); 
    var r = ea.Bounds; 
    r.Offset(ea.Bounds.Height, 0); 
    RadioButtonRenderer.DrawRadioButton(ea.Graphics, 
     new Point(ea.Bounds.Location.X, ea.Bounds.Location.Y + 2), r, text, 
     lb.Font, TextFormatFlags.Left, false, 
     (ea.State & DrawItemState.Selected) == DrawItemState.Selected ? 
     RadioButtonState.CheckedNormal : RadioButtonState.UncheckedNormal); 
}; 

截圖

你可以看到下面的圖片這兩個解決方案:

enter image description here

var list = new List<MyCustomObject>() { 
    new MyCustomObject(){ Mode= SomeModeType.firstMode}, 
    new MyCustomObject(){ Mode= SomeModeType.secondMode}, 
    new MyCustomObject(){ Mode= SomeModeType.thirdMode}, 
}; 
this.myCustomObjectBindingSource.DataSource = list; 
var dataSource = myCustomObjectBindingSource; 

備註

回答完這個問題後,我在這篇文章中創建並共享了一個RadioButtonList控件:WinForms RadioButtonList doesn't exist

它具有數據綁定支持,您可以使用此控件,如ListBox。要做到這一點,就足以將其綁定到你的模型的屬性,然後設置控件只是這樣的數據源:

radioButtonList1.DataSource = Enum.GetValues(typeof(YourEnumType)); 
+0

好,有趣,但沒有更多的simle方式呢? ._。 – DanilGholtsman

+0

不幸的是,除非將所有邏輯封裝在單個控件中,並將其命名爲'RadioButtonList',否則沒有更簡單的方法。 –

+0

另一種選擇(根本不那麼簡單)是使用所有者繪製的Listbox。我也會分享它。 –