Вводное тестирование результатов приводит к неправильным результатам в элементе Path с большими масштабными коэффициентами в свойстве RenderTransform
.
Следующий 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>
Как видно на изображении ниже, появляется курсор Hand
, хотя его положение вне формы.
С более крупным путём и меньшими масштабными факторами проблема исчезает, и курсор ведет себя так, как ожидалось.
<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>
Выполнение явного теста теста, подобного этому
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.
Теперь возникает вопрос: в чем причина такого поведения и как его можно избежать? Обратите внимание, что я не могу просто изменить исходные размеры элементов Path, поэтому ответ, подобный "не использовать масштабные факторы", не будет полезен.
Моим текущим обходным путем является не преобразование пути в RenderTransform, а преобразование данных вместо этого (путем применения преобразования к свойству Geometry.Transform
). Но поскольку может быть сложное заполнение (например, с помощью ImageBrush), мне также необходимо преобразовать кисти заливки (что связано не только с установкой их преобразования, но и с их окном просмотра).
Более того, фактическое преобразование - это не только масштабирование, но и матричная трансформация, которая также вращается и преобразуется.
Можно также отметить, что проблема также возникает с другими геометриями и дополнительными преобразованиями. Например, преобразованный Путь с 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>
Исправить с помощью небольших масштабных коэффициентов:
<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>