2010-10-21 45 views
0

我已經實現了大部分在我的Silverlight 4應用程序中工作的拖放操作。一旦用戶將形狀放到畫布上,我想使用Size & Child Decorators。我試圖實現示例代碼。下面的代碼是更大的應用程序的問題部分。在ViewBox/Canvas中查找子對象對象

Xmal位 -

<ScrollViewer Grid.RowSpan="1" Grid.Row="2" Grid.ColumnSpan="2" Grid.Column="2" Name="scrollViewer"> 
    <Viewbox Margin="0" MinWidth="400" MinHeight="500" 
     HorizontalAlignment="Left" VerticalAlignment="Top" Name="ViewBoxTestBuild"> 
     <Canvas x:Name="Camera1Canvas" telerikDragDrop:RadDragAndDropManager.AllowDrop="True" 
      Width="1200" Height="768" MouseLeftButtonDown="Camera1Canvas_MouseLeftButtonDown"> 
      <Image x:Name="Camera1Image" Source="timemagadj.jpg" Canvas.ZIndex="-1" 
        HorizontalAlignment="Left" VerticalAlignment="Top" /> 
      <local:Three_Line_Graphic x:Name="threeLineEditTool" 
        HorizontalAlignment="Left" Canvas.Left="594" Canvas.Top="621" /> 
      <l:Adorner x:Name="adorn" Canvas.ZIndex="100" /> 
     </Canvas> 
    </Viewbox> 
</ScrollViewer> 

C#代碼 -

private void Camera1Canvas_MouseLeftButtonDown(object sender, MouseButtonEventArgs e) 
     { 
      var sendingObj = sender as Canvas; 
      if (sendingObj == null) return; 
      foreach (UserControl l in VisualTreeHelper.FindElementsInHostCoordinates(e.GetPosition(null), sendingObj)) 
       { 
        if (l.Parent == Camera1Canvas) 
        { 
         adorn.AdornedElement = l as FrameworkElement; 
         adorn.adorned_MouseLeftButtonDown(l, e); 
         break; 
        } 
       } 
      base.OnMouseLeftButtonDown(e); 
     } 

我的問題是,當VisualTreeHelper.FindElementsInHostCoordinates叫上單擊鼠標左鍵事件,當我點擊任意對象,沒有返回的元素。我確定這是一個座標映射問題,但對於我來說這是一個新的領域,我不確定如何解決它。

回答

0

您需要將VisualTreeHelper線改爲

GeneralTransform transform = sendingObj.TransformToVisual(Application.Current.RootVisual); 
Point pnt = transform.Transform(e.GetPosition(sendingObj)); 
var elements = VisualTreeHelper.FindElementsInHostCoordinates(pnt,Application.Current.RootVisual); 
+0

你的建議仍然沒有返回元素。 – 2010-10-21 19:14:41

+0

編輯以顯示另一種方式。 SL座標系有點怪異,有幾個怪癖。 「VisualTreeHelper.FindElementsInHostCoordinates(pnt,sendingObj)」的「 – Stephan 2010-10-21 20:38:38

+0

」 – 2010-10-22 13:46:42

2

也許在你的情況下,沒有必要使用VisualTreeHelper方法。

既然你控制畫布裏面的元素,你知道它們的類型,你可以嘗試這樣的:

private void Camera1Canvas_MouseLeftButtonDown(object sender, MouseButtonEventArgs e) 
    { 
     var sendingObj = sender as Canvas; 
     if (sendingObj == null) return; 
     foreach (UserControl l in sendingObj.Children) 
      { 
       var position = e.GetPosition(l); 
       var lArea = new Rect(0,0,l.ActualWidth,l.ActualHeight); 
       if (lArea.Contains(position)) 
       { 
        adorn.AdornedElement = l as FrameworkElement; 
        adorn.adorned_MouseLeftButtonDown(l, e); 
        break; 
       } 
      } 
     base.OnMouseLeftButtonDown(e); 
    } 

這比命中測試更有效。但是,這隻適用於矩形區域可以接受的情況。

如果需要檢測比矩形等形狀,你可以爲你填充畫布用戶控件的情況下,使用下面的,只要:

private void Camera1Canvas_MouseLeftButtonDown(object sender, MouseButtonEventArgs e) 
    { 
     var sendingObj = sender as Canvas; 
     if (sendingObj == null) return; 

     var elements = VisualTreeHelper 
      .FindElementsInHostCoordinates(
       e.GetPosition(sendingObj), sendingObj); 

     foreach (var l in elements) 
     { 
      if (l is UserControl) 
      { 
       adorn.AdornedElement = l as FrameworkElement; 
       adorn.adorned_MouseLeftButtonDown(l, e); 
       break; 
      } 
     } 
     base.OnMouseLeftButtonDown(e); 
    } 
+0

我喜歡這個答案,我會在以後使用它。謝謝。 – 2010-10-22 18:10:58