简体   繁体   中英

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

I require the cursor of the form to change to the cursor Cursors.Hand when the user hovers the pointer over a node with a specifically named parent node.

The issue I am having in implementing this is regarding changing the cursor back to the default one when the user moves the pointer away from the TreeNode in concern.

I have handled the NodeMouseHover event of the TreeView control (as in the code snippet in the end) to change the pointer to the alternative cursor and back to the default cursor when the pointer is moved to another node, but this does not handle the case when the user moves the pointer away from the nodes to a, say, a blank area of the TreeView control.

My initial, and only, intuition regarding the solution to this problem was to get the location and calculate the area of the TreeNode s which require the cursor to change and check if the pointer is still on one of these on the event handler of the MouseMove event of the TreeView control, but, I believe, this is not an elegant solution as there are a lot of TreeNode s that require this behavior which would require looping through a lot of them for checking, which in turn may cause the application to be, in rare scenarios, a tad non-responsive.

Thanks in advance.

PS The code snippet in question:

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;
};

Handle the MouseMove instead, get a Node from the current mouse location, iterate backward to get the Parent (and the parent of the parent if any) of the current Node , and change the Cursor accordingly:

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;
    }
}

Also handle the MouseLeave event to check if there's a need to Default the Cursor .

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

Or if you prefer the Lambda way:

//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 is how I believe it must be done to incorporate the cursor changes when the cursor is moved sideways beyond the boundaries of the text of the node.

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;
     }
};

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM