C# 在鼠标悬停时设置状态栏文本-适用于控件,但不适用于菜单项

C# 在鼠标悬停时设置状态栏文本-适用于控件,但不适用于菜单项,c#,winforms,mouse,hover,menuitem,C#,Winforms,Mouse,Hover,Menuitem,我设计了以下代码,用于在mouseover上显示控件的标记属性。该代码适用于标签和文本框等标准控件,但无法用于MenuItems(更具体地说是ToolStripMenuItems)。你们能看看我的代码,告诉我我做错了什么吗?提前谢谢 public void Form1_Load(object sender, EventArgs e) { … this.添加所有组件(this); } private void addEventsToAllComponents(Component comp

我设计了以下代码,用于在mouseover上显示控件的标记属性。该代码适用于标签和文本框等标准控件,但无法用于MenuItems(更具体地说是ToolStripMenuItems)。你们能看看我的代码,告诉我我做错了什么吗?提前谢谢

public void Form1_Load(object sender, EventArgs e)
{

this.添加所有组件(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 = "";
}

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


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

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

尝试添加:

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

在处理菜单项的部分中,代码有一些问题

第一。MenuStrip的项不是该项的子项,因此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不是从控件派生的,因此在MouseEnter中,sender as Control语句将失败(控件将为null)。这样做:

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();
(我还添加了一些空检查)


这应该可以让你开始了。

以下是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);
    }
  }
}

谢谢你的建议;我会继续编写代码,看看是否能正常工作。我不知道IsNullOrEmpty,因为我对C#还不熟悉,但一般来说不懂编程。从现在起,我将在将来使用它。将MenuItem更改为ToolStripMenuItem并不能解决此问题。还有其他建议吗?谢谢你的建议。我没有对MenuItems使用递归,因为我没有意识到MenuItems是嵌套的,但我会为它编写代码。显然,ToolStripMenuItems没有isParent或有子项。对于ToolStripMenuItems,请使用:foreach(menuItem.DropDownItems中的ToolStripMenuItem项)。要测试“iParent”,请使用(menuItem.DropDownItems.Count>0)谢谢M-Peror!这就成功了。你就是那个男人!!!关于VS08、C#和WinForms,我想我还有很多东西要学习。我必须在代码中添加以下内容:“else if(control is ToolStrip){ToolStrip ts=control as ToolStrip;AddEventsToAllToolStripItems(ts.Items);}”。