C# C使用selectedvaluechanged的列表框

C# C使用selectedvaluechanged的列表框,c#,winforms,C#,Winforms,我通常都能把事情弄清楚,但这让我疲惫不堪 我在表单上有一个列表框数组和一个提交按钮。用户可以从任何列表框中选择项目,然后单击“提交”按钮以选择“确认项目”,但需要做的是,如果他们从列表框1中选择了某个项目,然后改变主意并从列表框2中选择了某个项目,则列表框1中选择的项目应变为未选择 我可以将其编码到EventHandler中,但问题是,只要我以编程方式更改另一个列表框中的值,它就会触发另一个事件。我似乎无法用逻辑来摆脱它 任何想法都将是伟大的,否则我想我将不得不把多个提交按钮 编辑: 最后,我找

我通常都能把事情弄清楚,但这让我疲惫不堪

我在表单上有一个列表框数组和一个提交按钮。用户可以从任何列表框中选择项目,然后单击“提交”按钮以选择“确认项目”,但需要做的是,如果他们从列表框1中选择了某个项目,然后改变主意并从列表框2中选择了某个项目,则列表框1中选择的项目应变为未选择

我可以将其编码到EventHandler中,但问题是,只要我以编程方式更改另一个列表框中的值,它就会触发另一个事件。我似乎无法用逻辑来摆脱它

任何想法都将是伟大的,否则我想我将不得不把多个提交按钮

编辑:

最后,我找到了一个我认为非常明显和简单的解决方案。我利用focused属性来区分用户或程序是否正在进行更改。适用于鼠标和键盘选择

谢谢你的建议

 for (int i = 0; i < treatments.Length; i = i + 1)
        {
            this.Controls.Add(ListBoxes[i]);
            this.Controls.Add(Labels[i]);
            this.Controls.Add(Spinners[i]);

            Labels[i].Top = vPosition - 20;
            Labels[i].Left = hPosition;
            Labels[i].Width = 600;

            ListBoxes[i].Left = hPosition;
            ListBoxes[i].Top = vPosition;
            ListBoxes[i].Width = 600;

            Spinners[i].Top = vPosition + ListBoxes[i].Height;
            Spinners[i].Left = hPosition + ListBoxes[i].Width - 60;
            Spinners[i].Width = 40;
            for (int d = 25; d > 0; d = d - 1) { Spinners[i].Items.Add((d).ToString()); }
            Spinners[i].SelectedIndex = 24;



            //EVENT HANDLER CODE that is executed if any selectetindexchange in any LIstbox in array
            ListBoxes[i].SelectedIndexChanged   += (sender, e) =>
                {


                    for (int s = 0; s < i; s = s + 1)

                    {
                        //FIND WHICH LBs[s] IS THE SENDING LISTBOX 
                        if (ListBoxes[s] == sender && ListBoxes[s].Focused == true)
                        {
                            string msg = "sender is ListBox " + s.ToString() + "\nFocus is" + ListBoxes[s].Focused.ToString();
                           // MessageBox.Show(msg);
                        }
                        else if(ListBoxes[s].Focused==false)
                        {
                            ListBoxes[s].SelectedIndex = -1;
                        }                        


                    }


                }; //end of event handler

}

我通常使用一个标志来解决这类问题,该标志让我知道我正在更改内容,因此我的事件处理程序可以检查该标志,而不会在这种情况下采取行动

private int codeChangingCount = 0;
private void combobox1_SelectedIndexChanged(object sender, EventArgs e) {
    codeChangingCount++;
    try {
        combobox2.SelectedIndex = someNewValue;
    } finally {
        codeChangingCount--;
    }
}

private void combobox2_SelectedIndexChanged(object sender, EventArgs e) {
    if (codeChangingCount == 0) {
        //I know this is changing because of the user did something, not my code above
    }
}

您可以使用简单的bool而不是int来实现这一点,但我喜欢计数器方法,这样我就可以在嵌套调用中不断增加codeChangingCount,而不会意外地重置它。在我的生产代码中,我有一个专门用于这种标记的类,它错误地使用IDisposable进行减量,因此我可以将调用包装在using块中,但上面的代码片段更简单,便于说明。

检查聚焦ListBox==ListBox2和SelectedIndex>-1,然后取消选择索引[0]

if (ListBoxes[s] == sender && ListBoxes[s].Focused == true)
    {
      if(s == 1 && ListBoxes[s].SelectedIndex > -1) //assuming 1 is listbox2
        {
          ListBoxes[0].SelectedIndex = -1; // Deselect ListBox1
        }
      string msg = "sender is ListBox " + s.ToString() + "\nFocus is" + ListBoxes[s].Focused.ToString();
    }

是Winforms、Webforms还是MVC项目?您可以始终使用标志。此问题类似,答案可能适用于一般策略:@kblok it s a Windows Forms将项目作为类添加,向其添加id属性以跟踪选择的列表框。然后将所有列表框指向同一个事件处理程序,通过检查id,您就知道选择了哪个。您可以循环浏览所有列表框,找出是否选择了两个以上的列表框,删除selectedvaluechanged事件,如果没有选择最后一个,则取消选择,然后添加回事件处理程序。我确实尝试过这种方法,但无法使其与我使用循环和一个事件处理程序处理多个列表框的方式配合使用。