2016-12-26 15 views
2

Предположим, у меня появилось несколько радиообъектов и некоторый пользовательский объект в качестве источника данных.Список RadioButton Windows Forms - привязать свойство 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 различных радиокнопок с чем-то вроде:

If radiobuttonOne проверяемых - свойство объекта mode множеств firstMode

Если radiobuttonTwo проверено - свойство объекта mode комплектов на secondMode

Если radiobuttonThree проверил - свойство объекта mode наборы для thirdMode

и т.д. и т.п.

Или его лучше использовать события для этого?

P.S. Я знаю, как использовать события, но его перегружать, чтобы создать событие по событию, например rb1chnaged, rb2changed, ..., rb100changed, разве это не так?

P.P.S.

MerryXmas!

+0

Когда вы объявляете перечисление типа это только одна запись. Вам нужна коллекция для привязки к списку радиокнопок. Попробуйте объявить свойство «List » как свойство и заполнить его каждым членом enum –

+0

@AnupSharma, но как это помогает? Я имею в виду, почему бы просто не связать с ним радиообъект - если вы выберете 1-е, тогда значение поля станет 'firstMode', а в случае 2-го - переписать значение поля в' secondMode' – DanilGholtsman

+0

. Я использовал элемент управления RadioButtonList [здесь] (http://stackoverflow.com/a/41355419/3110834). –

ответ

1

Для каждого значения перечисления необходимо создать RadioButton и привязать его значение Checked к объекту источника данных Mode. Затем вам необходимо использовать Format и Parse событие Binding для преобразования Mode значение в подходящее значение для Checked и наоборот.

Пример - RadioButton Список с использованием 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 может быть MyCustomObject или BindingList<MyCustomObject> или BindingSource, который содержит в своем DataSource в List<MyCustomObject>.

Другая альтернатива - RadioButton Список используя Владелец-раздаточный ListBox

В качестве другого варианта можно использовать владелец-рисовать ListBox и сделать RadioButton для деталей. Таким образом, вы можете связать SelectedValue от ListBox до 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

хорошо, интересно , но для этого нет более простого способа? ._. – DanilGholtsman

+0

К сожалению, нет, нет более простого способа, если вы не инкапсулируете всю логику в один элемент управления и не называете ее чем-то вроде «RadioButtonList». –

+0

Еще одна альтернатива (которая не является более простой) - использовать ListBox для владельца. Я тоже поделюсь этим. –