我正在制作一个绘图应用程序。为了使它的行为与数学图形相同,我将下面的转换应用于带有数据点的画布:
<UserControl.Resources>
<TransformGroup x:Key="CanvasTransform">
<TranslateTransform X="30" Y="30"/>
<ScaleTransform ScaleX="1" ScaleY="-1" CenterX=".5" CenterY=".5" />
</TransformGroup>
</UserControl.Resources>
以下是使用的转换方法:
<ListBox>
<ListBox.ItemsPanel>
<ItemsPanelTemplate>
<Canvas>
<Canvas.RenderTransformOrigin>
<Point X="0.5" Y="0.5"/>
</Canvas.RenderTransformOrigin>
<Canvas.RenderTransform>
<Binding Source="{StaticResource CanvasTransform}"/>
</Canvas.RenderTransform>
</Canvas>
</ItemsPanelTemplate>
</ListBox.ItemsPanel>
到目前为止一切都很好。问题在于如何向图表中添加点。因为鼠标单击事件返回的是窗口坐标,所以没有用。添加的点会出现在错误的位置,因为它是在添加后进行转换的。
例如,画布高度为400个单位。我在左上角单击鼠标,鼠标位置为
[X=10, Y=10]
,这个点被添加到图表中并呈现出来。然后呈现变换使用[10,10]点并计算它的新位置:[X=40,Y=360]
(窗口坐标)。这意味着我在顶部单击,点会出现在底部。这实际上是正确的行为。
我的问题是,如何在存储点之前手动应用渲染变换,使点出现在鼠标下方。
到目前为止,我尝试了以下方法:
var trans = Resources["CanvasTransform"] as TransformGroup;
var mouse = e.GetPosition(this); // mouse position relative to canvas
var newPoint = trans.Transform(mouse);
但是在这次变换后,
newPoint
的坐标变为[40,-39]
。我知道结果为什么会是这样。变换的原点是[0,0]
,平移量为29
,可能是由于四舍五入误差引起的。现在,我可以取出这个新点并手动更改值-从X坐标中减去
30
,然后将Canvas.ActualHeight
加到Y坐标中,这将修正位置。但这有什么意义呢?
我的问题是:是否可能以与渲染器相同的方式应用
RenderTransform
,以避免手动处理坐标?