自定义组框未绑定到绑定源
Custom group box not binding to bindingsource
我需要将 GroupBox
绑定到 BindingSource
,后者又绑定到以下对象:
public class CustomerType
{
public int Id {get; set;}
public string Name {get; set;}
public MemberType MemberType {get; set;}
}
public enum MemberType {Adult, Child}
我关注了这个answer to create a custom GroupBox。我还设置数据绑定如下:
groupBoxMemberType.DataBindings.Add("Selected", this.bindingSource, "MemberType");
但是,在加载现有对象时,出现以下异常:
DataBinding cannot find a row in the list that is suitable for all bindings.
设置数据源时出现异常:
customerType = customerTypeRequest.Load(id);
bindingSource.DataSource = customerType; //raises exception
我错过了什么?是否有替代方法让单选按钮绑定到数据源,特别是 BindingSource
?
这是更改后的代码:
[DefaultBindingProperty("Selected")]
public class RadioGroupBox : GroupBox
{
#region events
[Description("Occurs when the selected value changes.")]
public event SelectedChangedEventHandler SelectedChanged;
public class SelectedChangedEventArgs : EventArgs
{
public int Selected { get; private set; }
internal SelectedChangedEventArgs(int selected)
{
this.Selected = selected;
}
}
public delegate void SelectedChangedEventHandler(object sender, SelectedChangedEventArgs e);
#endregion
private int selected;
[Browsable(false)]
[Bindable(BindableSupport.Yes, BindingDirection.TwoWay)]
[Description("The selected value associated with this control."), Category("Data")]
public int Selected
{
get { return selected; }
set
{
int val = 0;
var radioButton = this.Controls.OfType<RadioButton>()
.FirstOrDefault(radio =>
radio.Tag != null
&& int.TryParse(radio.Tag.ToString(), out val) && val == value);
if (radioButton != null)
{
radioButton.Checked = true;
selected = val;
}
}
}
protected override void OnControlAdded(ControlEventArgs e)
{
base.OnControlAdded(e);
var radioButton = e.Control as RadioButton;
if (radioButton != null)
radioButton.CheckedChanged += radioButton_CheckedChanged;
}
protected void OnSelectedChanged(SelectedChangedEventArgs e)
{
if (SelectedChanged != null)
SelectedChanged(this, e);
}
private void radioButton_CheckedChanged(object sender, EventArgs e)
{
var radio = (RadioButton)sender;
int val = 0;
if (radio.Checked && radio.Tag != null
&& int.TryParse(radio.Tag.ToString(), out val))
{
selected = val;
OnSelectedChanged(new SelectedChangedEventArgs(selected));
}
}
}
除了将 Tag
属性 设置为枚举的相应 int 值外,您还需要在表单中订阅 SelectedChanged 事件,例如:
private void radioGroupBoxMemberType_SelectedChanged(object sender, SelectedChangedEventArgs e)
{
customerType.MemberType = (MemberType)e.Selected;
}
对此 class 的改进是:
继承自 RadioButton 并使用新的 属性 代替 Tag
属性.
直接在控件中访问并设置绑定源属性,避免订阅事件。
我需要将 GroupBox
绑定到 BindingSource
,后者又绑定到以下对象:
public class CustomerType
{
public int Id {get; set;}
public string Name {get; set;}
public MemberType MemberType {get; set;}
}
public enum MemberType {Adult, Child}
我关注了这个answer to create a custom GroupBox。我还设置数据绑定如下:
groupBoxMemberType.DataBindings.Add("Selected", this.bindingSource, "MemberType");
但是,在加载现有对象时,出现以下异常:
DataBinding cannot find a row in the list that is suitable for all bindings.
设置数据源时出现异常:
customerType = customerTypeRequest.Load(id);
bindingSource.DataSource = customerType; //raises exception
我错过了什么?是否有替代方法让单选按钮绑定到数据源,特别是 BindingSource
?
这是更改后的代码:
[DefaultBindingProperty("Selected")]
public class RadioGroupBox : GroupBox
{
#region events
[Description("Occurs when the selected value changes.")]
public event SelectedChangedEventHandler SelectedChanged;
public class SelectedChangedEventArgs : EventArgs
{
public int Selected { get; private set; }
internal SelectedChangedEventArgs(int selected)
{
this.Selected = selected;
}
}
public delegate void SelectedChangedEventHandler(object sender, SelectedChangedEventArgs e);
#endregion
private int selected;
[Browsable(false)]
[Bindable(BindableSupport.Yes, BindingDirection.TwoWay)]
[Description("The selected value associated with this control."), Category("Data")]
public int Selected
{
get { return selected; }
set
{
int val = 0;
var radioButton = this.Controls.OfType<RadioButton>()
.FirstOrDefault(radio =>
radio.Tag != null
&& int.TryParse(radio.Tag.ToString(), out val) && val == value);
if (radioButton != null)
{
radioButton.Checked = true;
selected = val;
}
}
}
protected override void OnControlAdded(ControlEventArgs e)
{
base.OnControlAdded(e);
var radioButton = e.Control as RadioButton;
if (radioButton != null)
radioButton.CheckedChanged += radioButton_CheckedChanged;
}
protected void OnSelectedChanged(SelectedChangedEventArgs e)
{
if (SelectedChanged != null)
SelectedChanged(this, e);
}
private void radioButton_CheckedChanged(object sender, EventArgs e)
{
var radio = (RadioButton)sender;
int val = 0;
if (radio.Checked && radio.Tag != null
&& int.TryParse(radio.Tag.ToString(), out val))
{
selected = val;
OnSelectedChanged(new SelectedChangedEventArgs(selected));
}
}
}
除了将 Tag
属性 设置为枚举的相应 int 值外,您还需要在表单中订阅 SelectedChanged 事件,例如:
private void radioGroupBoxMemberType_SelectedChanged(object sender, SelectedChangedEventArgs e)
{
customerType.MemberType = (MemberType)e.Selected;
}
对此 class 的改进是:
继承自 RadioButton 并使用新的 属性 代替
Tag
属性.直接在控件中访问并设置绑定源属性,避免订阅事件。