【问题标题】:Set Statusbar Text on Mouse Hover - Works for controls but not MenuItems在鼠标悬停时设置状态栏文本 - 适用于控件但不适用于 MenuItems
【发布时间】:2009-12-19 12:11:07
【问题描述】:

我设计了以下代码,用于在鼠标悬停时显示控件的 Tag 属性。该代码适用于标签和文本框等标准控件,但我无法让它适用于我的 MenuItems(更具体地说是 ToolStripMenuItems)。大家可以看看我的代码并告诉我我做错了什么吗?提前致谢!

public void Form1_Load(object sender, EventArgs e)

{

...

this.addEventsToAllComponents(this);

}

    private void addEventsToAllComponents(Component component)
{
  if (component is MenuItem)
  {
    MenuItem menuItem = component as MenuItem;
    menuItem.Select += new EventHandler(menuItem_Select);
  }
  else if (component is Control)
  {
    Control ctrl = component as Control;
    foreach (Control control in ctrl.Controls)
    {
      control.MouseEnter += new EventHandler(this.control_MouseEnter);
      control.MouseLeave += new EventHandler(this.control_MouseLeave);
      if (control.HasChildren)
        addEventsToAllComponents(control);
    }
  }
}

    private void menuItem_Select(object sender, EventArgs e)
{
  MenuItem menuItem = sender as MenuItem;

  if (menuItem.Tag.ToString().Length > 0)
    this.toolStripStatusLabel1.Text = menuItem.Tag.ToString();
}

private void control_MouseEnter(object sender, EventArgs e)
{
  Control control = sender as Control;

  if (control.Tag.ToString().Length > 0)
    this.toolStripStatusLabel1.Text = control.Tag.ToString();
}

private void control_MouseLeave(object sender, EventArgs e)
{
  if (this.toolStripStatusLabel1.Text.ToString().Length > 0)
    this.toolStripStatusLabel1.Text = "";
}

【问题讨论】:

    标签: c# winforms mouse hover menuitem


    【解决方案1】:

    您的代码存在一些问题。

    第一。 MenuStrip 的 Item 不是 Item 的子项,因此 HasChildren 将返回 false。相反,它们位于 MenuStrip 的 Items 集合中。您需要专门处理 MenuStrip 事件。 在下面的 AddEvents... 方法中添加以下代码:

    (snip...)
    // old code                    
    if (control.HasChildren)
        AddEventsToAllControls(control);
    //add new code below
    if (control is MenuStrip) {
        MenuStrip ms = control as MenuStrip;
        AddEventsToAllToolStripMenuitems(ms.Items);
    }
    

    并添加新方法如下:

    private void AddEventsToAllToolStripMenuitems (ToolStripItemCollection items) {
        foreach (ToolStripItem tsi in items) {
            tsi.MouseEnter += new EventHandler(this.control_MouseEnter);
            tsi.MouseLeave += new EventHandler(this.control_MouseLeave);
            if (tsi is ToolStripMenuItem) {
                ToolStripMenuItem mi = tsi as ToolStripMenuItem;
                AddEventsToAllToolStripMenuitems(mi.DropDownItems);
            }
        }
    }
    

    第二。 ToolStripItem 不是从 Control 派生的,因此在 MouseEnter 中,sender as Control 语句将失败(控件将为空)。做这样的事情:

    Control control = sender as Control;
    if (control != null && control.Tag != null && control.Tag.ToString().Length > 0)
        this.toolStripStatusLabel1.Text = control.Tag.ToString();
    
    ToolStripItem tsi = sender as ToolStripItem;
    if (tsi != null && tsi.Tag != null && tsi.Tag.ToString().Length > 0)
        this.toolStripStatusLabel1.Text = tsi.Tag.ToString();
    

    (我还添加了一些空检查)

    这应该能让你继续前进。

    【讨论】:

    • 感谢 M-Peror!那成功了。你是(我)人!!!我想我在 VS08、C# 和 WinForms 方面还有很多东西要学。
    • 我必须在您的代码中添加以下内容:“ else if (control is ToolStrip) { ToolStrip ts = control as ToolStrip; AddEventsToAllToolStripItems(ts.Items); }”。
    【解决方案2】:

    您没有任何代码来处理 ToolStripMenuItems - 它们不是从 MenuItems 派生的,因此您的 MenuItem 处理代码不会为它们做任何事情。

    另外:为了可读性,您可能希望使用string.IsNullOrEmpty(menuItem.Tag.ToString()) 来测试空/空白字符串。

    【讨论】:

    • 感谢您的建议;我将在代码上多做一些工作,看看我是否能让它正常工作。我不知道 IsNullOrEmpty,因为我是 C# 新手,但一般不会编程。从现在开始,我将在未来使用它。
    • 将 MenuItem 更改为 ToolStripMenuItem 并不能解决问题。还有其他建议吗?
    【解决方案3】:

    您没有为包含其他菜单项的MenuItems 设置递归。所以当它找到一个菜单项时,它只会添加顶级MenuItem,而不是子项。

    尝试添加:

    foreach (MenuItem item in menuItem.MenuItems)
    {
      item Select += new EventHandler(menuItem_Select);
      if (item.IsParent)
        addEventsToAllComponents(item);
    }
    

    在处理MenuItems的部分。

    【讨论】:

    • 感谢您的提示。我没有对 MenuItems 使用递归,因为我没有意识到 MenuItems 是嵌套的,但我会为其编写代码。
    • 显然,ToolStripMenuItems 没有 isParent 或 HasChildren。
    • 对于 ToolStripMenuItems,使用:foreach (ToolStripMenuItem item in menuItem.DropDownItems)。要测试“IsParent”,请使用 (menuItem.DropDownItems.Count > 0)
    【解决方案4】:

    这里是 AddEventsToAllComponents 方法的修改代码:

    private void addEventsToAllControls(Control ctrl)
    {
      foreach (Control control in ctrl.Controls)
      {
        control.MouseEnter += new EventHandler(this.control_MouseEnter);
        control.MouseLeave += new EventHandler(this.control_MouseLeave);
        if (control.HasChildren)
          addEventsToAllControls(control);
    
        if (control is MenuStrip)
        {
          MenuStrip ms = control as MenuStrip;
          AddEventsToAllToolStripItems(ms.Items);
        }
        else if (control is ToolStrip)
        {
          ToolStrip ts = control as ToolStrip;
          AddEventsToAllToolStripItems(ts.Items);
        }
      }
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2014-04-10
      • 2019-02-12
      • 2017-06-15
      • 2021-12-01
      • 1970-01-01
      • 1970-01-01
      • 2016-05-17
      相关资源
      最近更新 更多