【问题标题】:.NET Listbox: in ItemChecked event know if item was clicked.NET Listbox:在 ItemChecked 事件中知道是否单击了项目
【发布时间】:2011-08-19 17:07:15
【问题描述】:

我的 winforms 应用程序中有一个 ListBox,我需要处理 ItemChecked,因为每次用户单击项目时我都需要一些东西。问题是我还需要在表单的其他一些事件中更改 Checked 属性。在这些情况下,我需要避免这样做。

例子:

private void listBox1_ItemChecked(object sender, ItemCheckedEventArgs e)
{
  if (true) //Should check if item was clicked.
  {
     //Do some stuff
  }
  else //If the event was fired because I changed the Checked property from the code
  {
     //Do some other stuff
  }
}

谢谢

【问题讨论】:

    标签: c# .net winforms events listbox


    【解决方案1】:

    一种方法是使用布尔变量,比如说 ManualRaise。当您通过代码引发事件时,设置 ManualRaise = true 并在您的事件中检查'

    if(ManualRaise) 
    {
    // this was manual event raise
    ManualRaise = False
    } 
    else 
    {
    }
    

    在您将引发列表框事件的事件中,将 ManualRaise 设置为 true。

    【讨论】:

      【解决方案2】:

      如果我理解正确,我认为您想在后台更改 Checked 属性时取消订阅 ItemCheck 事件(即用户没有导致 Checked 属性更改)。

      例如:

      public void SetupListBoxEnables()
      {  
         // Do not listen for Checked change events
         listBox1.ItemCheck -= listBox1_ItemChecked;
         // Change a bunch of Checked properties
         // ....
      
         // Listen again for Checked change events
         listBox1.ItemCheck += listBox1_ItemChecked;
      }
      

      【讨论】:

      • @antisanity 和@SwDevMan81 也许我做silverlight 和WPF 的时间太长了,但这看起来很老套。我也完成了一些 winforms 开发的工作,并且总能找到解决问题的方法,而无需连接和取消连接事件。对我来说有太多的依赖。
      • 感谢您的解决方案。它确实有效,但首先它的代码比@haris 所说的拥有标志更多。另一方面(主要是)这个解决方案使我必须将//Do some other stuff 的代码放在我更改 Checked 属性的每个地方。
      【解决方案3】:

      我在类中保留一个布尔值,以跟踪用户何时执行操作或系统自动执行操作。每当我要更改时,例如 CheckBox.Checked,我将布尔值设置为 True,然后在完成后返回 False。

      在 Checked 事件处理程序中,我检查事件是否在布尔值为真时发生,以确定要执行的代码。

      private Boolean blnSystem = false;
      
      private void SystemChanges()
      {
          try
          {
              blnSystem = true;
      
              //Code which changes listBox1 Item Checked values
          }
          catch
          {
              //Error handler
          }
          finally
          {
              blnSystem = false;
          }
      }
      
      private void listBox1_ItemChecked(object sender, ItemCheckedEventArgs e)
      {
          if (!blnSystem) //Should check if item was clicked.
          {
              //Do some stuff
          }
          else //If the event was fired because I changed the Checked property from the code
          {
              //Do some other stuff
          }
      }
      

      【讨论】:

        【解决方案4】:

        到目前为止,您得到的所有答案都很棒。但是,我想知道是否将特定于编程设置选定列表项的逻辑放在实际设置选中属性的相同代码中而不是依赖于 ItemChecked 事件是否更有意义。该事件可以调用与前一个代码相同的代码。

        示例:

        public void SomeFunction()
        {
          // set checkbox
          listBox1.Items[index].Checked = true;
        
          // Handle the change in state
          HandleState();
        }
        
        protected void listBox1_ItemChecked(object sender, ItemCheckedEventArgs e) 
        {
          HandleState();
        }
        
           private function HandleState()
           {
              // Handle your visual state here
           }
        

        【讨论】:

        • 我真的无法理解您的解决方案。你能帮我弄到吗。还要记住,要触发 ItemChecked,您需要更改 Checked 属性,而不是 Selected。
        • @Diego 抱歉,我同时想到了两件事。实际上,您要查找的是选中的属性,而不是选定的属性。示例函数中的第一行代码不正确。至于理解解决方案,基本上你想要所谓的控制反转。而不是让 ItemChecked 事件控制 UI,而是“反转”并将 UI 的控制移动到更集中的位置。这允许事件发生,而无需担心这些事件的特定依赖关系。查看 MVC 模式以获得更多信息。
        • 我想我现在明白了。我选择了 flag 选项,因为它很简单,谢谢!
        • @Deigo 如果这是一个简单的程序,那么一定要使用标志。当您拥有包含许多交互元素的复杂 UI 时,MVC 非常有用。你能想象有数百个标志和标志的标志吗?随着您的 UI 变得越来越复杂,最终会发生什么。如果合适的话,我完全赞成 KISS,所以无论如何,如果这能解决你的问题,请使用标志方法。谢谢!
        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2011-08-06
        • 2010-10-22
        • 1970-01-01
        • 2013-10-26
        • 2021-07-01
        • 1970-01-01
        相关资源
        最近更新 更多