3 回答
TA贡献1772条经验 获得超6个赞
为了在不更改笔触粗细的情况下变换形状,可以使用Path具有变换后几何形状的对象。
以下XAML在画布上放置一个Image和两个路径。图像通过RenderTransform缩放和转换。相同的变换也用于Transform两个路径的几何属性。
<Canvas>
<Image Source="C:\Users\Public\Pictures\Sample Pictures\Desert.jpg">
<Image.RenderTransform>
<TransformGroup x:Name="transform">
<ScaleTransform ScaleX="0.5" ScaleY="0.5"/>
<TranslateTransform X="100" Y="50"/>
</TransformGroup>
</Image.RenderTransform>
</Image>
<Path Stroke="Orange" StrokeThickness="2">
<Path.Data>
<RectangleGeometry Rect="50,100,100,50"
Transform="{Binding ElementName=transform}"/>
</Path.Data>
</Path>
<Path Stroke="Orange" StrokeThickness="2">
<Path.Data>
<EllipseGeometry Center="250,100" RadiusX="50" RadiusY="50"
Transform="{Binding ElementName=transform}"/>
</Path.Data>
</Path>
</Canvas>
您的应用程序现在可以简单地更改transform对象以响应MouseMove或MouseWheel之类的输入事件。
当还要转换TextBlocks或其他不应该缩放但只能移动到适当位置的元素时,事情会变得有些棘手。
您可以创建一个专门的面板,该面板可以将这种转换应用于其子元素。这样的面板将定义一个控制子元素位置的附加属性,并将变换应用于该位置而不是子元素RenderTransform或LayoutTransform的位置。
这可以使您了解如何实施这样的小组:
public class TransformPanel : Panel
{
public static readonly DependencyProperty TransformProperty =
DependencyProperty.Register(
"Transform", typeof(Transform), typeof(TransformPanel),
new FrameworkPropertyMetadata(Transform.Identity,
FrameworkPropertyMetadataOptions.AffectsArrange));
public static readonly DependencyProperty PositionProperty =
DependencyProperty.RegisterAttached(
"Position", typeof(Point?), typeof(TransformPanel),
new PropertyMetadata(PositionPropertyChanged));
public Transform Transform
{
get { return (Transform)GetValue(TransformProperty); }
set { SetValue(TransformProperty, value); }
}
public static Point? GetPosition(UIElement element)
{
return (Point?)element.GetValue(PositionProperty);
}
public static void SetPosition(UIElement element, Point? value)
{
element.SetValue(PositionProperty, value);
}
protected override Size MeasureOverride(Size availableSize)
{
var infiniteSize = new Size(double.PositiveInfinity,
double.PositiveInfinity);
foreach (UIElement element in InternalChildren)
{
element.Measure(infiniteSize);
}
return new Size();
}
protected override Size ArrangeOverride(Size finalSize)
{
foreach (UIElement element in InternalChildren)
{
ArrangeElement(element, GetPosition(element));
}
return finalSize;
}
private void ArrangeElement(UIElement element, Point? position)
{
var arrangeRect = new Rect(element.DesiredSize);
if (position.HasValue && Transform != null)
{
arrangeRect.Location = Transform.Transform(position.Value);
}
element.Arrange(arrangeRect);
}
private static void PositionPropertyChanged(
DependencyObject obj, DependencyPropertyChangedEventArgs e)
{
var element = (UIElement)obj;
var panel = VisualTreeHelper.GetParent(element) as TransformPanel;
if (panel != null)
{
panel.ArrangeElement(element, (Point?)e.NewValue);
}
}
}
它将在XAML中像这样使用:
<local:TransformPanel>
<local:TransformPanel.Transform>
<TransformGroup>
<ScaleTransform ScaleX="0.5" ScaleY="0.5" x:Name="scale"/>
<TranslateTransform X="100"/>
</TransformGroup>
</local:TransformPanel.Transform>
<Image Source="C:\Users\Public\Pictures\Sample Pictures\Desert.jpg"
RenderTransform="{Binding Transform, RelativeSource={RelativeSource Mode=FindAncestor, AncestorType=local:TransformPanel}}"/>
<Path Stroke="Orange" StrokeThickness="2">
<Path.Data>
<RectangleGeometry Rect="50,100,100,50"
Transform="{Binding Transform, RelativeSource={RelativeSource Mode=FindAncestor, AncestorType=local:TransformPanel}}"/>
</Path.Data>
</Path>
<Path Stroke="Orange" StrokeThickness="2">
<Path.Data>
<EllipseGeometry Center="250,100" RadiusX="50" RadiusY="50"
Transform="{Binding Transform, RelativeSource={RelativeSource Mode=FindAncestor, AncestorType=local:TransformPanel}}"/>
</Path.Data>
</Path>
<TextBlock Text="Rectangle" local:TransformPanel.Position="50,150"/>
<TextBlock Text="Ellipse" local:TransformPanel.Position="200,150"/>
</local:TransformPanel>
TA贡献1828条经验 获得超3个赞
可以选择将哪些变换应用于哪些元素吗?有没有一种方法可以有选择地应用,或者忽略该变换。除了Path
厚度和文本不缩放外,我需要所有图层都像一幅图像一样工作,另外我还需要能够Path
在图像上移动,调整大小,旋转并选择每个图层。今天我已经完成所有这些工作。是我的滚动查看器和笔触粗细。我将尝试您的自定义Panel
想法,看看是否有什么突出之处并报告。
- 3 回答
- 0 关注
- 2334 浏览
添加回答
举报