代码之家  ›  专栏  ›  技术社区  ›  photo_tom

在ViewBox/Canvas对象中查找子对象

  •  0
  • photo_tom  · 技术社区  · 15 年前

    我已经实现了一个拖放,主要是在我的Silverlight4应用程序中工作。一旦用户将图形放到画布上,我就想使用 Size & Child Decorators . 我试过实现示例代码。下面的代码是更大的应用程序的问题部分。

    圣诞节-

    <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>
    

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

    我的问题是,当在鼠标左键单击事件上调用visualtreeehelper.FindElementsInHostCoordinates时,当我单击任何对象时,它都不会返回任何元素。我确信这是一个坐标映射问题,但由于这对我来说是一个新的基础,我不确定如何解决它。

    2 回复  |  直到 15 年前
        1
  •  0
  •   Stephan    15 年前

    您需要将VisualTreeHelper行更改为

    GeneralTransform transform = sendingObj.TransformToVisual(Application.Current.RootVisual);
    Point pnt = transform.Transform(e.GetPosition(sendingObj));
    var elements = VisualTreeHelper.FindElementsInHostCoordinates(pnt,Application.Current.RootVisual);
    
        2
  •  2
  •   Murven    15 年前

    也许在您的情况下不需要使用visualtreeheloper方法。

    由于您控制画布中的元素并知道它们的类型,因此可以尝试以下操作:

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

    比命中测试更有效。但是,这只在矩形区域可以接受的情况下才有效。

    如果需要检测矩形以外的形状,只要在画布中填充UserControl实例,就可以使用以下命令:

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