0

いくつかの GraphNodes を描画し、それらを ContentControls としてキャンバスに追加するキャンバスがあります。すべてのグラフ ノードには、ノードから別のノードへの接続線を描画するために使用する装飾があります。アドナーにはメソッド OnMouseUp があります。

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

この時点で、最初の GraphNode である AdornedElement で線を描画し始めたソース ノードがあります。また、マウスが離された座標もあります。このポイントの下には別の GraphNode があります。このポイントの下にあるノードを見つける方法は?

ありがとうございました。

4

1 に答える 1

0

OK、多くの調査の後、私は解決策を見つけました:

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

そして、GraphNode を見つけるための HitTest メソッド。GraphNode はカスタム オブジェクトであることを思い出してください。

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;
}
于 2012-10-08T08:57:33.383 に答える