2012-10-03 109 views
0

我有一個畫布,其中繪製一些GraphNodes並將它們作爲ContentControls添加到畫布。所有圖形節點都有一個裝飾器,我用它來繪製從一個節點到另一個節點的連接線。裝飾器具有的方法OnMouseUp:WPF從鼠標位置獲取視覺

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

此時我有從那裏我開始畫在AdornedElement線作爲初始GraphNode源節點。另外,我還有鼠標釋放的座標。在這一點下是另一個GraphNode。如何找到這一點下的節點?

謝謝。

+0

不[e.OriginalSource](http://msdn.microsoft.com/en-us/library/system.windows.routedeventargs.originalsource.aspx)或[e.Source](HTTP:// msdn.microsoft.com/en-us/library/system.windows.routedeventargs.source.aspx)有幫助嗎? – LPL

+0

不是。它始終是AdornedElement,它是源代碼。我想找到目標節點,我在哪裏生成MouseUpEvent。 – alexandrudicu

+1

然後在此處查看:[在可視層中擊中測試](http://msdn.microsoft.com/zh-cn/library/ms752097.aspx) – LPL

回答

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

然後是的HitTest方法找到GraphNode。請記住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; 
}