我使用ItemsControl在画布上定位集合中的项目。定位由TranslateTransform:<TranslateTransform X="{Binding x}" Y="{Binding y}"/>
完成。为了使项目可以点击,我在项目上实现了MouseLeftButtonUp事件。
请参阅以下完整代码:
<ItemsControl ItemsSource="{Binding XYPoints}">
<ItemsControl.ItemsPanel>
<ItemsPanelTemplate>
<Canvas/>
</ItemsPanelTemplate>
</ItemsControl.ItemsPanel>
<ItemsControl.ItemTemplate>
<DataTemplate>
<Ellipse Width="20" Height="20" Fill="Red" MouseLeftButtonUp="XYPlotPoint_MouseLeftButtonUp">
<Ellipse.RenderTransform>
<TransformGroup>
<RotateTransform Angle="0"/>
<TranslateTransform X="{Binding x}" Y="{Binding y}"/>
</TransformGroup>
</Ellipse.RenderTransform>
</Ellipse >
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
我无法弄清楚的是:我希望能够点击我的任何项目并获取TranslateTransform坐标,即用于在画布上定位元素的x和y值。
我的想法是在将发件人转换回Ellipse之后从事件的发件人那里得到这个,例如Ellipse myEllipse = (Ellipse)sender;
但我没有看到任何包含该信息的属性。
如果我使用GeneralTransform gt = myEllipse.TransformToVisual(Application.Current.RootVisual);
它只给我相对于RootVisual的Transform,而不是我正在绘制的网格。
也许我忽略了一些显而易见的事情。我会感激任何提示。
答案 0 :(得分:0)
我不太确定你的问题是什么,但我想我已经得到了它。
您正在使用一种非常奇怪的方法来定位Canvas
中的项目。这是你的方法,使得获得点击支持变得如此困难。你只需要把所有物品都放在一起。您只需在不同的位置渲染它们,而布局和输入系统则认为所有项目都位于坐标系原点。这就是为什么所有鼠标事件都不起作用的原因。
主流方法是通过其附加属性Canvas.Left
和Canvas.Top
,如MSDN所示。尝试通过ItemContainerStyle
:
<ItemsControl ItemsSource="{Binding XYPoints}">
<ItemsControl.ItemsPanel>
<ItemsPanelTemplate>
<Canvas/>
</ItemsPanelTemplate>
</ItemsControl.ItemsPanel>
<ItemsControl.ItemTemplate>
<DataTemplate>
<Ellipse Width="20" Height="20" Fill="Red" MouseLeftButtonUp="XYPlotPoint_MouseLeftButtonUp"/>
</DataTemplate>
</ItemsControl.ItemTemplate>
<ItemsControl.ItemContainerStyle>
<Style>
<Setter Property="Canvas.X" Value="{Binding x, Mode=TwoWay}"/>
<Setter Property="Canvas.Y" Value="{Binding y, Mode=TwoWay}"/>
</Style>
</ItemsControl.ItemContainerStyle>
</ItemsControl>
一旦这样做,您的MouseLeftButtonUp
事件只有在用户点击该项时才会被触发,您无需计算所点击项目的位置。
答案 1 :(得分:0)
我找到了解决方案。要获得相对于另一个UIElement
点击的UIElement
(我的项目)的转换(在我的情况下放置Grid
,这也是LayoutRoot
}):
private void XYPlotPoint_MouseLeftButtonUp(object sender, MouseButtonEventArgs e)
{
//cast sender to original type
Ellipse myEllipse = (Ellipse)sender;
//get the transform relative to the LayoutRoot
GeneralTransform gt = myEllipse.TransformToVisual(LayoutRoot);
//transform a new point to get the coordinates
var myUiElementPosition = gt.Transform(new Point(0, 0));
}