2010-10-21 46 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