Finding Child Objects in ViewBox/Canvas Object
I've implemented a drag and drop that is mostly working in my Silverlight 4 app. Once the users have dropped the shapes onto the canvas, I wanted to use Siz开发者_运维百科e & Child Decorators. I've tried to implement the sample code. Code below is problem section of much larger app.
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# code -
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);
}
My problem is that when VisualTreeHelper.FindElementsInHostCoordinates is called on left mouse click event, it returns no elements when I click on any object. I sure that it is a coordinate mapping issue, but as this is new ground for me, I'm unsure how to fix it.
Maybe in your case there is no need to use the VisualTreeHelper method.
Since you control the elements inside the canvas and you know their type, you can try something like this:
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);
}
Which is more efficient than hit-testing. However, this only works if rectangular areas are acceptable.
If you need to detect shapes other than rectangles, you can use the following, as long as you are filling a canvas with instances of 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);
}
You need to change your VisualTreeHelper line to
GeneralTransform transform = sendingObj.TransformToVisual(Application.Current.RootVisual);
Point pnt = transform.Transform(e.GetPosition(sendingObj));
var elements = VisualTreeHelper.FindElementsInHostCoordinates(pnt,Application.Current.RootVisual);
精彩评论