当用户将鼠标悬停在 TreeView 控件的特定 TreeNode 控件上时显示不同的光标

Displaying a different cursor when the user hovers the mouse over a particular TreeNode control of a TreeView control

我要求当用户将指针悬停在具有专门命名的父节点的节点上时,表单的光标更改为光标 Cursors.Hand

我在实现这个问题时遇到的问题是当用户将指针从相关 TreeNode 移开时将光标更改回默认值。

我已经处理了 TreeView 控件的 NodeMouseHover 事件(如最后的代码片段中所示)以将指针更改为替代光标并在指针时返回默认光标被移动到另一个节点,但是当用户将指针从节点移到一个,比方说,TreeView 控件的空白区域时,这不处理这种情况。

关于这个问题的解决方案,我最初的也是唯一的直觉是获取位置并计算需要光标更改的 TreeNodes 的面积,并检查指针是否仍在一个上这些在 TreeView 控件的 MouseMove 事件的事件处理程序上,但是,我相信,这不是一个优雅的解决方案,因为有很多 TreeNode 需要这种行为这将需要循环遍历其中的大量内容以进行检查,这反过来可能会导致应用程序在极少数情况下有点无响应。

提前致谢。

PS 有问题的代码片段:

this.treeView.NodeMouseHover += delegate (object sender, TreeNodeMouseHoverEventArgs e)
{
   bool isNewCursorAssigned = false;
   if (e.Node.Parent != null)
   {
      if (e.Node.Parent.Text == "someTxt")
      {
         this.Cursor = Cursors.Hand;
         isNewCursorAssigned = true;
      }
   }
   if (isNewCursorAssigned == false && this.Cursor != this.DefaultCursor)
      this.Cursor = this.DefaultCursor;
};

改为处理 MouseMove,从当前鼠标位置获取 Node,向后迭代以获取当前鼠标的 Parent(以及父项的父项,如果有的话) Node,并相应地更改 Cursor

private void treeView1_MouseMove(object sender, MouseEventArgs e)
{
    var node = treeView1.GetNodeAt(e.Location);

    if (node != null)
    {
        var parent = node.Parent;

        while (parent != null)
        {
            if (parent.Text == "someTxt")
            {
                if (Cursor != Cursors.Hand)
                            Cursor = Cursors.Hand;
                        return;
            }
            parent = parent.Parent;
        }
        Cursor = Cursors.Default;
    }
}

同时处理 MouseLeave 事件以检查是否需要 默认 Cursor.

private void treeView1_MouseLeave(object sender, EventArgs e)
{
    if (Cursor != Cursors.Default)
        Cursor = Cursors.Default;
}

或者如果您更喜欢 Lambda 方式:

//In the constructor:

treeView1.MouseMove += (s, e) =>
{
    var node = treeView1.GetNodeAt(e.Location);

    if (node != null)
    {
        var parent = node.Parent;
        while (parent != null)
        {
            if (parent.Text == "someTxt")
            {
                if (Cursor != Cursors.Hand)
                    Cursor = Cursors.Hand;
                return;
            }
            parent = parent.Parent;
        }
        Cursor = Cursors.Default;
    }
};

treeView1.MouseLeave += (s, e) =>
{
    if (Cursor != Cursors.Default)
        Cursor = Cursors.Default;
};

我认为当光标横向移动超出节点文本边界时,必须采用这种方式合并光标更改。

this.treeView.MouseMove += delegate (object sender, MouseEventArgs e)
{
     TreeNode concernedNode = this.treeViewOfAvailableMachines.GetNodeAt(e.Location);
     if (concernedNode != null)
        if (!(concernedNode.Parent != null && concernedNode.Parent.Text == "someTxt"))
               concernedNode = null;
     if (concernedNode != null)
     {
          if ((e.Location.X >= concernedNode.Bounds.Location.X &&
                    e.Location.X <= concernedNode.Bounds.Location.X + concernedNode.Bounds.Width) &&
                    (e.Location.Y >= concernedNode.Bounds.Location.Y &&
                    e.Location.Y <= concernedNode.Bounds.Location.Y + concernedNode.Bounds.Height))
          {
               this.Cursor = Cursors.Hand;
          }
          else
          {
               this.Cursor = this.DefaultCursor;
          }
     }
     else
     {
          this.Cursor = this.DefaultCursor;
     }
};