【问题标题】:BindingSource with Generic SubClass in Windows FormsBindingSource 与 Windows 窗体中的通用子类
【发布时间】:2010-03-04 16:25:02
【问题描述】:

我正在尝试在 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 的集合,并将我的comboboxdatasource 设置为该集合。 (这部分工作正常,组合框正确显示值。)然后我将comboboxSelectedValue 绑定设置为BindingSourceChoice 属性更新OnPropertyChanged.

如果我在组合框中选择一个值时将 IntegerClass 替换为非泛型类,则 BindingSource 的 Choice 属性会发生更改,NotifyPropertyChanged 事件会被触发,并且在我的表单上我可以更新一个标签,上面写着“Choice has changed!”。

当 IntegerClass 是 ClassBindingClass 的一部分时,这将不再起作用,而是我无法导航出组合框,而是获得 FormatException

我想做的事可能吗?数据绑定可以处理泛型吗?

【问题讨论】:

    标签: c# winforms generics data-binding


    【解决方案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);
        }
    }
    

    【讨论】:

    • 两个问题:如果我想使用SelectedItem 而不是SelectedValue 为什么这适用于没有通用子类的类?我可以将 IntegerClass 更改为普通类并且代码有效,这非常令人困惑。您上面的代码是否解决了为什么它与SelectedItem 一起使用但仅在控件失去焦点时才有效的问题?
    • “当控件失去焦点时”是暴露通知事件和属性(一起)DataSourceUpdateMode的组合。其余的 - 你能提供一个比较的例子吗?
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2010-10-25
    • 2010-09-16
    • 2016-01-11
    • 1970-01-01
    相关资源
    最近更新 更多