数据绑定的组合框不在SelectedItem上更新其数据源

时间:2017-01-05 08:45:48

标签: c# winforms data-binding

我有一个数据绑定组合框。它的约束如下:

cbo.DataBindings.Add(new Binding("SelectedItem", this.bindingSource, "Order", true, DataSourceUpdateMode.OnPropertyChanged, null));

它的填充如下:

cbo.DataSource = customer.Orders.Where(x => x.Month == month).ToList();
cbo.ValueMember = "OrderId";
cbo.DisplayMember = "OrderDate";
cbo.SelectedIndex = -1;

数据源是BindingSource,它又绑定到DTO类。

如果我选择一个项目并使用TAB将焦点移至另一个控件,则SelectedItem设置正确。

但是,如果我选择一个项目并点击另一个控件,那么当标签退出控件时,SelectedItem将成为之前选择的项目。

我尝试过绑定SelectedItemSelectedValueOnPropertyChangedOnValidation的混合物,但如果没有标记,则会导致同样的问题。

在此SO answer中给出了部分解决方案,但是,就我而言,它不起作用。

目前的解决方法是:

(bindingSource.Current as Customer).Order = selectedOrder;

这应该是不必要的,因为数据源是绑定的。有没有更好的方法来强制在单击另一个控件而不是标签时提交更改?

2 个答案:

答案 0 :(得分:1)

问题是ComboBox没有提供正确绑定到SelectedItemChanged所需的SelectedItem事件。

您应该绑定到SelectedValue,这样可以正常工作。问题是无法指定使用DisplayMember作为显示,将数据源对象指定为ValueMember。解决它的一种方法是使用专用对象(a.k.a.视图模型)作为列表元素。例如,使用匿名类型投影:

cbo.DisplayMember = "OrderDate";
cbo.ValueMember = "Order";
cbo.DataSource = customer.Orders.Where(x => x.Month == month)
    .Select(o => new { o.OrderDate, Order = o })
    .ToList();

cbo.DataBindings.Add(new Binding("SelectedValue", bindingSource, "Order", true, DataSourceUpdateMode.OnPropertyChanged, null));

答案 1 :(得分:0)

理论上" OnPropertyChanged"当控件失去焦点时,将强制执行数据绑定以将值写入底层对象。但不知怎的,它没有;所以我想在某处数据绑定没有正确完成:

  1. 是绑定到正确对象的数据绑定吗?

  2. 是否在更改绑定对象时清除了先前的数据绑定?

  3. 您是否尝试直接将this.bindingSource更改为您的对象,而不是通过bindingSource包装器?

  4. 通常,如果您希望强制将数据写回对象以进行数据绑定,则可以调用binding.WriteValue()。

    如下所示:

        cbo.LostFocus += (object sender, EventArgs e) => {
            foreach (Binding b in cbo.DataBindings)
            {
                if (string.Equals(b.PropertyName, "SelectedItem"))
                {
                    b.WriteValue();
                }                    
            }
        };