我想要在Windows窗体应用程序中使用Ctrl-Left ori Ctrl-Right更改组合框的选定值。但是,如果组合框是表单上的选定控件,则不起作用。将所选值设置为新值后,将其设置为旧值。如果组合框不是选定的控件,那么一切正常。在我的应用程序中,组合可以获得焦点,因为也可以使用鼠标更改值。虽然我想要的是通过在实际更改值之前选择表单上的其他控件来实现,但我不太喜欢这个解决方案。
因此,有两个问题:如果组合框是表单上的选定控件,为什么使用旧值触发selectedIndexChanged事件? 如何避免这种情况或者我不能解决什么是好的解决方法?还有一些代码来说明我的问题。如果您删除表单上的组合框和richtext框并将下面的代码复制到Form1.cs中,您可以看到我的问题。你需要制作组合DropDownList样式并添加一些数字作为项目(1,2,3很好)
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
comboBox1.SelectedIndex = 0;
}
protected override bool ProcessCmdKey(ref Message msg, Keys keyData)
{
if (keyData == (Keys.Control | Keys.Left))
{
DoUpdate();
}
return base.ProcessCmdKey(ref msg, keyData);
}
private void DoUpdate()
{
int index = Convert.ToInt32(comboBox1.SelectedItem);
index++;
if (comboBox1.Focused)
richTextBox1.Select();
comboBox1.SelectedItem = index.ToString();
}
private void SetComboValue(int value)
{
comboBox1.SelectedItem = value.ToString();
richTextBox1.AppendText(string.Format("Set value {0} \r\n", value.ToString()));
}
private void comboBox1_SelectedIndexChanged(object sender, EventArgs e)
{
richTextBox1.AppendText(string.Format("Selected index changed before {0}\r\n", comboBox1.SelectedItem));
SetComboValue(Convert.ToInt32(comboBox1.SelectedItem));
richTextBox1.AppendText(string.Format("Selected index changed after {0}\r\n", comboBox1.SelectedItem));
}
}
答案 0 :(得分:1)
这是由于默认情况下,如果组合框具有焦点,则左右按下(无控制)将改变该值。
您正在捕捉ctrl-left,递增值...然后将按键传递给基础对象,该对象解释左按键并减少所选项目。
按如下方式更改您的代码,以吞下按键,事情似乎按预期工作:
protected override bool ProcessCmdKey(ref Message msg, Keys keyData)
{
if (keyData == (Keys.Control | Keys.Left))
{
DoUpdate();
return true;
}
else
{
return base.ProcessCmdKey(ref msg, keyData);
}
}
答案 1 :(得分:0)
为什么不从DoUpdate方法运行SetComboValue方法?如果这不起作用,您可以始终设置一个标志,指出它是从DoUpdate方法设置的,并且只在直接访问时运行选定的索引更改事件。只是一个想法。
当我们在表单加载过程中遇到与组合框和列表相关的大量事件时,我们会做类似的事情。我们正在设置值,并且不希望在加载期间触发事件,因此我们有一个标志可以阻止事件触发,直到表单加载完成。
我的想法是你正在设置值,但是其他东西正在迫使第二个选择项更改事件发生。但是,由于您在DoUpdate方法和SetComboValue方法中设置selectedindex,因此看起来您可能会进入无限循环。
只需在一个地方更改所选索引。