WPF从鼠标位置获取视觉 [英] WPF get visual from mouse position

查看:222
本文介绍了WPF从鼠标位置获取视觉的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个画布,其中绘制了一些GraphNodes并将它们作为ContentControls添加到画布中。所有图形节点都有一个装饰器,我可以用它来绘制从一个节点到另一个节点的连接线。装饰者具有OnMouseUp方法:

I have a canvas where a draw some GraphNodes and add them to the canvas as ContentControls. All graph nodes have an adorner which I use to draw connection lines from a node to another node. The adorner has a method OnMouseUp:

protected override void OnMouseUp(System.Windows.Input.MouseButtonEventArgs e)
{
    var SourceNode = AdornedElement;
    Point pt = PointToScreen(Mouse.GetPosition(this));
    var DestinationNode = ???
}

这时,我有了源节点,从此处开始画线在AdornedElement中,它是初始的GraphNode。另外,我有释放鼠标的坐标。在这一点下是另一个GraphNode。

At this point I have the source node from where I started to draw the line in in AdornedElement which is the initial GraphNode. Also, I have the coordinates where the mouse was released. Under this point is another GraphNode. How to find the node that is under this point ?

谢谢。

推荐答案

好,经过大量研究,我找到了一个解决方案:

OK, after many research I have found a solution:

protected override void OnMouseUp(System.Windows.Input.MouseButtonEventArgs e)
{ 
   Point pt = PointToScreen(Mouse.GetPosition(this));
   UIElement canvas = LogicalTreeHelper.GetParent(AdornedElement) as UIElement;
   // This is important to get the mouse position relative to the canvas, otherwise it won't work
   pt = canvas.PointFromScreen(pt);
   VisualTreeHelper.HitTest(canvas, null, HitTestResultCallbackHandler, new PointHitTestParameters(pt));            
}

然后使用HitTest方法来找到GraphNode。请记住GraphNode是自定义对象。

And then the HitTest method to find the GraphNode. Remember that GraphNode is a custom object.

public HitTestResultBehavior HitTestResultCallbackHandler(HitTestResult result)
{
   if (result != null)
   {
      // Search for elements that have GraphNode as parent
      DependencyObject dobj = VisualTreeHelper.GetParent(result.VisualHit);
      while (dobj != null && !(dobj is ContentControl))
      {
         dobj = VisualTreeHelper.GetParent(dobj);
      }
      ContentControl cc = dobj as ContentControl;   
      if (!ReferenceEquals(cc, null))
      {
         IEnumerable<DependencyObject> dependencyObjects = cc.GetSelfAndAncestors();
         if (dependencyObjects.Count() > 0)
            {
                IEnumerable<ContentControl> contentControls = dependencyObjects.Where(x => x.GetType() == typeof(ContentControl)).Cast<ContentControl>();
                if (contentControls.Count() > 0)
                    {
                       ContentControl cControl = contentControls.FirstOrDefault(x => x.Content.GetType() == typeof(GraphNode));
                        if (cControl != null)
                        {
                            var graphNode = cControl.Content as GraphNode;
                            if (!ReferenceEquals(graphNode, null))
                            {
                               // Keep the result in a local variable
                               m_DestinationNode = graphNode;
                               return HitTestResultBehavior.Stop;
                            }
                        }                           
                    }
                }
            }               
        }
    m_DestinationNode = null;
    return HitTestResultBehavior.Continue;
}

这篇关于WPF从鼠标位置获取视觉的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆