gpt4 book ai didi

wpf - 对转换后的路径进行不正确的 HitTest

转载 作者:行者123 更新时间:2023-12-03 00:52:13 27 4
gpt4 key购买 nike

RenderTransform 属性中具有较大缩放因子的 Path 元素上,输入命​​中测试会产生不正确的结果。

以下 XAML 定义了一个带有实心圆和Hand 光标的 Path。

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

如下图所示,手形光标出现,尽管它的位置远离形状。

enter image description here

使用较大的路径和较小的缩放因子,问题就会消失并且光标的行为符合预期。

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

enter image description here

执行像这样的显式 HitTest

private void Canvas_MouseLeftButtonDown(object sender, MouseButtonEventArgs e)
{
var canvas = (UIElement)sender;
var hitElement = canvas.InputHitTest(e.GetPosition(canvas));
Trace.TraceInformation("hitElement = {0}", hitElement);
}

在 Canvas 上的鼠标事件处理程序中给出了相同的错误结果。在缩放路径之外明显单击鼠标仍会将路径返回为命中元素。

还值得注意的是,该问题不会出现在 Silverlight 中。

<小时/>

现在的问题是:这种行为的原因是什么以及如何避免?请注意,我不能简单地更改路径元素的原始大小,因此“不要使用大比例因子”之类的答案不会有帮助。

我当前的解决方法是不通过 RenderTransform 转换路径,而是转换数据(通过将转换应用于 Geometry.Transform 属性)。但由于可能存在复杂的填充(例如使用 ImageBrush),我也必须变换填充画笔(这不仅涉及设置它们的变换,还涉及它们的视口(viewport))。

而且,实际的变换不仅仅是缩放,而是还旋转和平移的 MatrixTransform。

<小时/>

还值得注意的是,其他几何图形和附加变换也会出现该问题。例如,带有 RectangleGeometry 的转换后的 Path 显示出类似的错误行为。

对于大比例因子不正确:

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

enter image description here

使用小比例因子时正确:

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

enter image description here

最佳答案

更多的是扩展评论而不是答案:

这似乎是奇怪的行为,我尝试了一些Paths,并尝试使用 Geometry.GetWidenedPathGeometry对数据本身应用稍微不同的缩放效果,但没有走得太远。

问题的根本原因似乎是 WPF 中选择命中检测容差的方式,Brendan Clark 在 MSDN 上对类似问题有两个答案,似乎从未修复过。

本质上,使用的 HitTest 容差似乎是从几何体本身的基本尺寸导出的绝对值,而不是渲染/转换的尺寸。因此,虽然这对于您正在制作的较小的大形状,或者实际上是您保持较小的小形状来说很好,但当按比例放大小形状时,它会开始变得非常不准确(正如您所发现的)。

即相对于小形状的大小进行小的 HitTest 公差是可以的,但是当形状和公差都按比例放大时,这开始看起来很糟糕。

在一个线程中建议的解决方案是将形状放大到您需要的最大尺寸,并在您希望它们更小时时缩小它们(这不是适合您的解决方案)。呃。

看起来你可能会陷入一些转变的困境。我会尝试看看是否能想出更好的办法。

我正在查看的链接:

http://social.msdn.microsoft.com/Forums/vstudio/en-US/8708e340-f734-4cf4-b91d-28b49fee2b72/hittest-is-buggy-not-accurate-for-transformed-scaled-etc-visuals?forum=wpf

http://social.msdn.microsoft.com/Forums/vstudio/en-US/b307676b-d8b2-4af0-9f6f-1e150eed97ba/hittesting-with-a-scaled-path-doesnt-work?forum=wpf

关于wpf - 对转换后的路径进行不正确的 HitTest ,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/19324094/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com