Winforms的ComboBox SelectedItem改变不影响BindingSource

本文关键字:影响 BindingSource 改变 SelectedItem ComboBox Winforms | 更新日期: 2023-09-27 18:17:37

我正在制作c#/WinForms应用程序。我无法解决(尚未)的问题是,当我以编程方式改变ComboBox的SelectedItem时,它会被改变,直到ComboBox失去焦点,之后它在分配SelectedItem之前"提醒"它的值。我认为它从绑定源中获取旧值。当使用UI选择一个项目时,底层绑定对象正常更新,但当我以编程方式为SelectedItem分配新值时,它不会更新。

只是为了额外的信息:我正试图实现"撤销",这意味着我在某个地方保存每一个更改,当编辑>>>撤销我正在逆转用户所做的所有这些更改。有趣的是,其他控件(TextBoxes, NumericUpDowns)工作良好。

详情如下:

我有一个ComboBox,我像这样将它绑定到ComboItem对象:

ComboBox comboBox = new ComboBox();
List<ComboItem> items = new List<ComboItem>();
ComboList comboList = Configuration.ComboList.LoadComboList();
Combo myCombo = comboList.GetCombo(control.MemberName);
if (myCombo != null)
{
    items.Add(new ComboItem(0, "", 0.0, 0.0));
    for (int index = 0; index < myCombo.ComboItems.Count; index++)
    {
        items.Add(myCombo.ComboItems[index]);
    }
}

其中Combo和ComboList是用于从配置文件加载数据的自定义类。然后我设置了Display和Value成员以及DataSource:

comboBox.DisplayMember = "Text";
comboBox.ValueMember = "Key";
comboBox.DataSource = items;

"Text"answers"Key"是ComboItem类的成员:

public class ComboItem
{
    public int Key { get; set; }
    public string Text { get; set; }
    public double Coef1 { get; set; }
    public double Coef2 { get; set; } 
    public void CopyValues() {...}
    public override bool Equals() {...}
}

现在的问题是:当执行撤销时,我检查所有需要的东西,使所有的强制转换操作安全和清晰,并试图用以下代码"撤销":

Logger.Info(controls[0], op, "ExecuteUndo");
((ComboBox)controls[0]).Focus();
((ComboBox)controls[0]).SelectedItem = (ComboItem)op.GetOldValue();
Logger.Info(controls[0], "AFTER CHANGE");

Logger正在记录日志。op对象从撤销序列中获取,并使用"GetOldValue()"给出适当的值。这些代码实际上是在影响UI,但直到控件失去焦点。它发生在下一次撤销,应该影响其他控件,从而使这个组合框失去焦点。

我确信这发生在comboBox_LostFocus事件上,因为我在这个事件上做的第一件事是Logging,它已经显示了我不应该出现的值

Winforms的ComboBox SelectedItem改变不影响BindingSource

我认为您看到的问题是ComboBox显示一个值,但尚未将值写入绑定源(直到您失去焦点才发生)。

您可以尝试这样做,当一个项目被选中时写入数据(假设只有一个与ComboBox相关联的数据绑定):

private void comboBox_SelectedIndexChanged(object sender, EventArgs e) {
  comboBox.DataBindings[0].WriteValue();
}

为了确保,您要么从设计器订阅这个事件,要么手动连接它:

public Form1() {
  InitializeComponent();
  comboBox.SelectedIndexChanged += comboBox_SelectedIndexChanged;
}