データバインドをシンプルに
DataBindings
概要
設定クラス等をコントロールにデータバインドする場合について、
値が変更されたときに、現在値と比較して違っている場合だけ OK ボタンをクリック可能にしたい場合がある。
これを実現するには、通常、下記の手順で実装となる。
- 設定クラスを作成
- 設定クラスに INotifyPropertyChanged インターフェイスを実装
- 編集用コントロールを配置
- コントロールに設定クラスのインスタンスをデータバインド
が、INotifyPropertyChanged インターフェイスをいちいち実装するのが面倒。。
INotifyPropertyChanged インターフェイスは必要か
例えば、TextBox にデータバインドする場合、DataSourceUpdateMode を OnPropertyChanged にしても、プロパティの値が変更されるタイミングは、TextChanged イベントの後になるため、このイベントで値を比較しても正しい結果は得られない。
解決案
TextChanged イベントが発生したらデータソースを更新する処理を手動で入れてやる!
static void BindData(this Control control, string propertyName, object dataSource, string dataMember, Action onChanged = null)
{
//control.DataBindings.Clear();
var binding = control.DataBindings.Add(propertyName, dataSource, dataMember, true, DataSourceUpdateMode.Never);
if (binding != null)
{
// デフォルトイベント発生時に手動でデータソースを更新
// (DataSourceUpdateMode.OnPropertyChanged だと、TextBox.TextChanged イベント後にデータソースが更新されるため)
var defaultEvent = control.GetType().GetDefaultEvent();
if (defaultEvent != null)
{
defaultEvent.AddEventHandler(control, new EventHandler((sender, e) =>
{
binding.WriteValue();
onChanged?.Invoke();
}));
}
else binding.DataSourceUpdateMode = DataSourceUpdateMode.OnPropertyChanged;
}
}
値変更時のイベントは、コントロールによって TextChanged だったり ValueChanged だったりするため、DefaultEventAttribute で指定されているイベントを取得する。
static EventInfo GetDefaultEvent(this Type type) => type.GetEvent(type.GetAttribute<DefaultEventAttribute>()?.Name ?? string.Empty);
static TAttribute GetAttribute<TAttribute>(this ICustomAttributeProvider element, bool inherit = true) where TAttribute : Attribute
{
if (element == null) throw new ArgumentNullException(nameof(element));
return element.GetCustomAttributes(typeof(TAttribute), inherit).FirstOrDefault() as TAttribute;
}
各コントロールと Default 属性値
Control | DefaultProperty | DefaultEvent | DefaultBindingProperty |
---|---|---|---|
TextBox | Text | TextChanged | Text |
CheckBox | Checked | CheckedChanged | CheckState |
RadioButton | Checked | CheckedChanged | Checked |
NumericUpDown | Value | ValueChanged | Value |
DateTimePicker | Value | ValueChanged | Value |
DataGridView | Text | CellContentClick | - |
Author And Source
この問題について(データバインドをシンプルに), 我々は、より多くの情報をここで見つけました https://qiita.com/Apeworks/items/c3e6afd12bfe8fe2f821著者帰属:元の著者の情報は、元のURLに含まれています。著作権は原作者に属する。
Content is automatically searched and collected through network algorithms . If there is a violation . Please contact us . We will adjust (correct author information ,or delete content ) as soon as possible .