我正在制作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”和“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");
记录器只是记录。 op对象取自undo序列,并使用“GetOldValue()”给出适当的值。该代码实际上是影响UI,但直到控件失去焦点。它会在下次撤消时发生,这会影响其他控制,从而让这个组合框失去焦点。
我确信这会发生在comboBox_LostFocus事件中,因为我在这个事件上做的第一件事是Logging,它已经显示了我不应该的值。
答案 0 :(得分:14)
我认为您遇到的问题是ComboBox
显示一个值,但尚未将值写入绑定源(直到您失去焦点才会发生这种情况)。
你可以尝试做这样的事情来在选择一个项目时写入数据(假设只有一个数据绑定与ComboBox
相关联):
private void comboBox_SelectedIndexChanged(object sender, EventArgs e) {
comboBox.DataBindings[0].WriteValue();
}
为了确保您能够从设计师订阅此活动,或者手动连接它:
public Form1() {
InitializeComponent();
comboBox.SelectedIndexChanged += comboBox_SelectedIndexChanged;
}