Windows窗体RadioButton列表 - 将枚举属性绑定到RadioButton

时间:2016-12-26 09:53:43

标签: c# winforms data-binding radio-button radiobuttonlist

我们说我有几个radiobuttons和一些自定义对象作为数据源。

例如

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个不同的radiobutton,例如:

如果选中radiobuttonOne,则对象属性mode设置为firstMode

如果选中radiobuttonTwo,则对象属性mode设置为secondMode

如果选中radiobuttonThree,则对象属性mode设置为thirdMode

等等

或者更好地为此使用事件?

P.S。 我知道如何使用事件,但它不知所措,可以按rb1chnagedrb2changed,...,rb100changed之类的事件创建事件,不是吗?

P.P.S。

MerryXmas!

1 个答案:

答案 0 :(得分:3)

对于枚举的每个值,您需要创建RadioButton并将其Checked值绑定到数据源的Mode属性。然后,您需要使用Format的{​​{1}}和Parse事件将Binding值转换为Mode属性的合适值,反之亦然。

示例 - 使用FlowLayoutPanel的RadioButton列表

例如,在表单上添加Checked控件,然后在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); }); 可以是dataSourceMyCustomObjectBindingList<MyCustomObject>,其BindingSource中包含List<MyCustomObject>

另一种选择 - 使用Owner-draw ListBox的RadioButton List

作为另一种选择,您可以使用所有者绘制DataSource并为项目呈现ListBox。这样,您就可以将RadioButton的{​​{1}}绑定到对象的SelectedValue属性。以下代码中的ListBox可以与上面的示例类似。在表单上放置Mode并在dataSourcs形式的事件中编写以下代码:

ListBox

<强>截图

您可以在以下图片中看到这两种解决方案:

enter image description here

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); }; 控件:WinForms RadioButtonList doesn't exist

它具有数据绑定支持,您可以像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