Вводное тестирование результатов дает неверные результаты по элементу Path с большими масштабными коэффициентами в свой 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>
Как можно видеть на изображении ниже, 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);
}
в обработчик событий мыши на холсте дает те же неправильные результаты. Щелчок мышью, явно за пределами масштабированного пути, по-прежнему возвращает элемент «Путь» как элемент удара.
Также стоит отметить, что проблема не появляется в 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>
Решение: * не использовать масштабные коэффициенты *. Нет, просто шучу. Это происходит, если вы изменили «RenderTranform» на «LayoutTransform»? –
Уже пытался, что хотя LayoutTransform не будет вариантом. Во всяком случае, он ведет себя одинаково с LayoutTransform. – Clemens
Вы рассматривали использование 'RectangleGeometry.Transform' вместо' Path. [Render | Layout] Transform'? Поскольку у вас есть доступ к самой геометрии, вы можете заставить свою фигуру визуализировать уже преобразованную геометрию, а затем ударное тестирование должно быть более естественным. – heltonbiker