きっかけ
C#をはじめて2年経ちますが、今さらデータバインディングをまじめにやってみた。
テキストボックスとかコンボボックスなら簡単に出来るけど、ラジオボタンだと複数のラジオボタンと1つのプロパティをうまく対応させられなかった(´・ω・`)
そんなわけでGroupBoxにラジオボタン用のプロパティを実装してみました。
tomochan.Forms
[ClassInterface(ClassInterfaceType.AutoDispatch)]
[Designer("System.Windows.Forms.Design.GroupBoxDesigner, System.Design, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a")]
[DefaultEvent("Enter")]
[DefaultProperty("Text")]
public partial class RadioGroupBox : GroupBox, INotifyPropertyChanged
{
public RadioGroupBox()
{
RadioButtons = new List<RadioButton>();
InitializeComponent();
}
public RadioGroupBox(IContainer container)
{
RadioButtons = new List<RadioButton>();
container.Add(this);
InitializeComponent();
}
protected List<RadioButton> RadioButtons { get; private set; }
protected override void OnControlAdded(ControlEventArgs e)
{
var radio = e.Control as RadioButton;
if (radio != null)
{
RadioButtons.Add(radio);
radio.CheckedChanged += RadioButton_CheckedChanged;
}
base.OnControlAdded(e);
}
protected override void OnControlRemoved(ControlEventArgs e)
{
var radio = e.Control as RadioButton;
if (radio != null)
{
radio.CheckedChanged -= RadioButton_CheckedChanged;
RadioButtons.Remove(e.Control as RadioButton);
}
base.OnControlRemoved(e);
}
protected virtual void RadioButton_CheckedChanged(object sender, EventArgs e)
{
OnPropertyChanged("Value");
}
[DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
public virtual string Value
{
get
{
var radio = RadioButtons.Find(c => c.Checked);
return radio == null ? "" : radio.Text;
}
set
{
var radio = RadioButtons.Find(c => c.Text == value);
if (radio == null)
{
throw new ArgumentException();
}
radio.Checked = true;
OnPropertyChanged("Value");
}
}
public event PropertyChangedEventHandler PropertyChanged;
protected virtual void OnPropertyChanged(string name)
{
PropertyChangedEventHandler handler = PropertyChanged;
if (handler != null)
{
handler(this, new PropertyChangedEventArgs(name));
}
}
}
form1
public partial class Form1 : Form
{
class Person
{
public string Name { get; set; }
public string Sex { get; set; }
}
public Form1()
{
InitializeComponent();
// グループボックスに男/女のラジオボタンを配置してあります
groupBox1.DataBindings.Add("Value", person, "Sex");
}
}
今後の課題
文字列で設定するところが残念な感じなので Enum とか使えるようにしたいけど、上手いこと設計できませんでした('A`)
とりあえずインデックスで指定できるようにしてお茶を濁すか!(゚∀゚)
ドキュメントアウトラインの順番に依存して落とし穴にハマりそうだけどw