输入命中测试在其RenderTransform属性中具有大缩放因子的Path元素上产生不正确的结果.
以下XAML定义了带有实心圆和Hand光标的路径.
<Canvas Background="LightGray">
<Path StrokeThickness="0" Fill="Blue" Cursor="Hand">
<Path.Data>
<EllipseGeometry RadiusX=".5" RadiusY=".5" Center="1,1"/>
</Path.Data>
<Path.RenderTransform>
<ScaleTransform ScaleX="150" ScaleY="150"/>
</Path.RenderTransform>
</Path>
</Canvas>
Run Code Online (Sandbox Code Playgroud)
如下图所示,Hand尽管光标的位置在形状之外,但仍会出现光标.

使用较大的Path和较小的缩放因子,问题消失,并且Cursor按预期运行.
<Canvas Background="LightGray">
<Path StrokeThickness="0" Fill="Blue" Cursor="Hand">
<Path.Data>
<EllipseGeometry RadiusX="50" RadiusY="50" Center="100,100"/>
</Path.Data>
<Path.RenderTransform>
<ScaleTransform ScaleX="1.5" ScaleY="1.5"/>
</Path.RenderTransform>
</Path>
</Canvas>
Run Code Online (Sandbox Code Playgroud)

像这样执行明确的命中测试
private void Canvas_MouseLeftButtonDown(object sender, MouseButtonEventArgs e)
{
var canvas = (UIElement)sender;
var hitElement = canvas.InputHitTest(e.GetPosition(canvas));
Trace.TraceInformation("hitElement = {0}", hitElement);
}
Run Code Online (Sandbox Code Playgroud)
在Canvas上的鼠标事件处理程序中给出了相同的错误结果.在缩放路径之外清楚地点击鼠标仍然会将Path作为命中元素返回.
还值得注意的是,Silverlight中没有出现此问题.
现在的问题是:这种行为的原因是什么,如何避免?请注意,我不能简单地更改Path元素的原始大小,因此像"不使用大比例因子"这样的答案将没有用.
我目前的解决方法不是通过RenderTransform转换Path,而是转换Data(通过将转换应用于Geometry.Transform属性).但由于可能存在复杂的填充(例如,使用ImageBrush),我也必须转换填充画笔(这不仅涉及设置其变换,还涉及它们的视口).
此外,实际变换不仅是缩放,而且还是一个也可以旋转和翻译的MatrixTransform.
值得注意的是,该问题也出现在其他几何形状和其他变换中.例如,带有RectangleGeometry的转换路径显示类似的错误行为.
大比例因子不正确:
<Canvas Background="LightGray">
<Path StrokeThickness="0" Fill="Blue" Cursor="Hand">
<Path.Data>
<RectangleGeometry Rect=".5,.5,1,1"/>
</Path.Data>
<Path.RenderTransform>
<TransformGroup>
<ScaleTransform ScaleX="150" ScaleY="150"/>
<RotateTransform Angle="45" CenterX="150" CenterY="150"/>
<TranslateTransform X="100"/>
</TransformGroup>
</Path.RenderTransform>
</Path>
</Canvas>
Run Code Online (Sandbox Code Playgroud)

纠正小规模因素:
<Canvas Background="LightGray">
<Path StrokeThickness="0" Fill="Blue" Cursor="Hand">
<Path.Data>
<RectangleGeometry Rect="50,50,100,100"/>
</Path.Data>
<Path.RenderTransform>
<TransformGroup>
<ScaleTransform ScaleX="1.5" ScaleY="1.5"/>
<RotateTransform Angle="45" CenterX="150" CenterY="150"/>
<TranslateTransform X="100"/>
</TransformGroup>
</Path.RenderTransform>
</Path>
</Canvas>
Run Code Online (Sandbox Code Playgroud)

更多的是扩展评论而不是答案:
这似乎是奇怪的行为,我玩了一些Paths,并尝试使用Geometry.GetWidenedPathGeometry对数据本身应用稍微不同的缩放效果,但没有走得太远。
问题的根本原因似乎是 WPF 中选择命中检测容差的方式,Brendan Clark 在 MSDN 上对类似问题有两个答案,似乎从未修复过。
本质上,使用的命中测试容差似乎是从几何体本身的基本尺寸导出的绝对值,而不是渲染/转换的尺寸。因此,虽然这对于您正在制作的较小的大形状,或者实际上是您保持较小的小形状来说很好,但当按比例放大小形状时,它会开始变得非常不准确(正如您所发现的)。
即,相对于小形状的大小进行小的命中测试公差是可以的,但是当形状和公差都按比例放大时,这开始看起来很糟糕。
一个线程中建议的解决方案是将形状放大到您需要的最大尺寸,并在您希望它们更小时时缩小它们(这不是适合您的解决方案)。呃。
看起来你可能会陷入一些转变的困境。我会尝试看看是否能想出更好的办法。
我正在查看的链接:
| 归档时间: |
|
| 查看次数: |
1153 次 |
| 最近记录: |