我正在尝试做我认为BindingSource和ComboBox之间的简单数据绑定。当我使用的类作为BindingSource的DataSource有一个属性是泛型类的实例时,我遇到了问题。
我有以下通用类:
public class GenericClass<T>
{
public T Code { get; set; }
public string Description { get; set; }
public override string ToString()
{
return Description;
}
}
我有一个具有整数代码的类:
public class IntegerClass : GenericClass<int>
{
// Nothing unique here, for simple test.
}
我还有一个设置为BindingSource的DataSource的类:
public class ClassBindingClass : INotifyProperty Changed
{
private int _id;
private IntegerClass _choice;
private string _name;
public int Id
{
get { return _id; }
set
{
_id = value;
OnPropertyChanged("Id");
}
}
public IntegerClass Choice
{
get { return _choice; }
set
{
_choice = value;
OnPropertyChanged("Choice");
}
}
public string Name
{
get { return _name; }
set
{
_name = value;
OnPropertyChanged("Name");
}
}
public event PropertyChangedEventHandler PropertyChanged;
protected virtual void OnPropertyChanged(string propertName)
{
if (PropertyChanged != null)
PropertyChanged(this, new PropertyChangedEventArgs(propertName));
}
}
在我的表单上,我创建了一个IntegerClass
的集合,并将combobox
的{{1}}设置为该集合。 (这部分工作正常,组合框会正确显示值。)然后我将datasource
的{{1}}绑定设置为combobox
的{{1}}属性更新{ {1}}
如果我在组合框中选择一个值时将IntegerClass替换为非泛型类,则BindingSource的Choice属性会更改NotifyPropertyChanged事件被触发,在我的表单上我可以更新标签“选择已更改!”。 / p>
当IntegerClass是ClassBindingClass的一部分时,它不再起作用,而是我无法导航到组合框之外而是获得SelectedValue
。
我想做的是什么?数据绑定可以处理泛型吗?
答案 0 :(得分:1)
你提到SelectedValue
...但你的源(和绑定属性)都是IntegerClass
- 所以它不是你要绑定的值,但是项目本身。不幸的是,没有ComboBox.SelectedItemChanged
所以你可能需要破解它以获得双向绑定......
static class Program {
[STAThread]
static void Main() {
Application.EnableVisualStyles();
IntegerClass[] choices = new[] {
new IntegerClass { Code = 123, Description = "a b c"},
new IntegerClass { Code = 456, Description = "d e f"},
new IntegerClass { Code = 789, Description = "g h i"},
};
ComboBox cbo = new TwoWayComboBox();
cbo.DropDownStyle = ComboBoxStyle.DropDownList;
cbo.DataSource = choices;
Form form = new Form();
ClassBindingClass obj = new ClassBindingClass();
cbo.DataBindings.Add("SelectedItem", obj, "Choice", true, DataSourceUpdateMode.OnPropertyChanged);
form.DataBindings.Add("Text", obj, "Choice", true, DataSourceUpdateMode.OnPropertyChanged); // show it
form.Controls.Add(cbo);
Application.Run(form);
}
}
class TwoWayComboBox : ComboBox {
public new object SelectedItem
{
get { return base.SelectedItem; }
set { base.SelectedItem = value; }
}
private static readonly object SelectedItemChangedKey = new object();
public event EventHandler SelectedItemChanged {
add { Events.AddHandler(SelectedItemChangedKey, value);}
remove { Events.RemoveHandler(SelectedItemChangedKey, value);}
}
protected override void OnSelectedIndexChanged(EventArgs e)
{
EventHandler handler = (EventHandler)Events[SelectedItemChangedKey];
if (handler != null) { handler(this, EventArgs.Empty); }
base.OnSelectedIndexChanged(e);
}
}