【问题标题】:Detecting which control is active检测哪个控件处于活动状态
【发布时间】:2012-10-11 08:23:29
【问题描述】:

我有一个带有文本框和列表框的设置,我希望列表框仅在文本框或列表框获得焦点时才可见。首先列表框将是不可见的。然后,当文本框聚焦时,列表框应该是可见的。只有当其中一个失去焦点并且都没有接收到它时,列表框才会再次变得不可见。所以我想要实现的是以下始终是真实的:

listBox.Visible = textBox.Focused || listBox.Focused

在我的解决方案中,文本框和/或列表框可以是标准类型的特化(如果这简化了解决方案)。

我已经尝试监听 LostFocus 和 GotFocus 两个控件的事件,并在那里设置列表框的可见性。但是,从不在列表框上调用 GotFocus 事件,因为当文本框失去焦点时我将其变为不可见。

有人对如何实现这一目标提出建议吗?我的备用计划(我不喜欢)是在一个人失去焦点时启动计时器,如果另一个人获得焦点则停止。因此,将不胜感激一种“更清洁”的实现方式;)

编辑:我正在开发它以用作 .NET WinForms 自定义控件。

编辑 2:

看来我对自己的解释还不够好。因此,我将尝试更明确地解释我想要实现的目标。

我正在创建一种新类型的 TextBox(继承我几年前构建的现有类型的 TextBox)。 TextBox 当前用作对象的通用集合(包括实现 IList 的子类型)。 TextBox 定义了一个 ListBox,它根据一组标准显示集合中元素的子集。由于 TextBox 被添加到父控件中,因此 ListBox 也是如此。因此,这两者作为一种在集合中搜索元素的设置工作。有点像你的浏览器在你开始输入时提出建议。

我使用此设置而不是包含两个控件的 UserControl,因为后者会导致 usercontrol 成为两个控件的大小,或者(当大小与 TextBox 匹配时)ListBox 不可见。

我意识到我可以选择在添加此控件的表单中的所有控件上处理 GotFocus 或 Enter 事件。这是我想到的一种非常简单的方法,但我更喜欢编写一个不监听表单中每个其他控件的控件。

我希望这可以澄清。

【问题讨论】:

    标签: c# .net textbox listbox focus


    【解决方案1】:

    将所有控件 Control_Enter 事件集中实施并检查发送者对象是您的文本框还是列表框,然后列表框将可见,否则不可见。

    这样

    this.button1.Enter += new System.EventHandler(this.Control_Enter);
       this.textBox1.Enter += new System.EventHandler(this.Control_Enter);
       this.listBox1.Enter += new System.EventHandler(this.Control_Enter);
    
    private void Control_Enter(object sender, EventArgs e)
        {
            Control obj = (Control)sender;
            if (obj.Name == "textBox1" || obj.Name == "listBox1")
            {
                listBox1.Visible = true;
            }
            else
            {
                listBox1.Visible = false;
            }
        }
    

    别忘了分配控制标签索引

    【讨论】:

      【解决方案2】:

      您可以做的是将Enter 事件处理程序添加到表单上的所有其他 控件。

      private void OtherControls_Enter(object sender, EventArgs e)
      {
        listBox.Visible = false;
      }
      

      编辑:
      示例适用于 WinForms,但也适用于 WPF。

      如果自定义控件仅包含TextBoxListBox,那么您将事件添加到TextBox 以设置ListBox 可见:

      private void textBox1_Enter(object sender, EventArgs e)
      {
        listBox1.Visible = true;
      }
      

      如果还有其他控件,请向它们添加 OtherControls_Enter 事件处理程序。

      在自定义控件的Leave 事件中添加如下内容:

      private void userControl11_Leave(object sender, EventArgs e)
      {
        userControl11.Controls["listbox1"].Visible = false;
      }
      

      编辑 2:
      更好的是从自定义控件中公开ListBox

      public ListBox TheListBox { get { return listBox1; } }
      

      然后:

      private void userControl11_Leave(object sender, EventArgs e)
      {
        userControl11.TheListBox.Visible = false;
      }
      

      【讨论】:

      • 我对这种方法的唯一问题是我正在开发一个自定义控件(我可能应该提到过),因此我必须为所有控件添加处理程序,因为这个自定义控件被添加到表格或面板。添加/删除所有这些处理程序的过程(包括向表单添加/删除控件时)将很快导致事件混乱。此外,不知道向控件添加了哪些其他类型的处理程序。
      • 另外,没有“OnFocus”事件。我假设您的意思是“GotFocus”事件,并且您的事件处理程序已正确命名。
      • 您使用的是什么技术? WPF? ASP.NET?表格?自定义控件包含什么?只有 TextBox 和 ListBox?
      • 更新了我的问题,以便它回答你的问题。我不知道 enter 事件的工作方式类似于 gotfocus - 但这对我不起作用。我没有创建包含两个控件的用户控件。在这一点上,我可能应该重新写下我的问题,以更准确地解释我想要实现的目标。
      • 我尝试了上述方法,效果很好。您真正需要的只是这三个事件处理程序。只需将它们连接到正确的控件即可。 IE。在自定义控件中的所有其他控件上重用OtherControls_Enter。这当然假设 ListBox 在自定义控件中。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-06-15
      • 1970-01-01
      相关资源
      最近更新 更多