我有一个画布控件,我在其中动态添加不同的形状。我已经通过使用 ScaleTransform 实现缩放并通过 TranslateTransform 平移。如果我必须放大和缩小而不调整画布中的形状(即调整画布大小而不调整其子项的大小),我将如何实现这一目标?
谢谢,
BR,
以下简单派生的 Canvas 将其子元素排列在由它们的Canvas.Left
和Canvas.Top
属性值给定的变换位置。转换由ChildPositionTransform
依赖属性应用。
public class ZoomCanvas : Canvas
{
public static readonly DependencyProperty ChildPositionTransformProperty =
DependencyProperty.Register(
"ChildPositionTransform", typeof(Transform), typeof(ZoomCanvas),
new FrameworkPropertyMetadata(
Transform.Identity, FrameworkPropertyMetadataOptions.AffectsArrange));
public Transform ChildPositionTransform
{
get { return (Transform)GetValue(ChildPositionTransformProperty); }
set { SetValue(ChildPositionTransformProperty, value); }
}
protected override Size ArrangeOverride(Size finalSize)
{
foreach (UIElement element in InternalChildren)
{
var x = GetLeft(element);
var y = GetTop(element);
var pos = new Point(double.IsNaN(x) ? 0d : x, double.IsNaN(y) ? 0d : y);
ArrangeElement(element, ChildPositionTransform.Transform(pos));
}
return finalSize;
}
private void ArrangeElement(UIElement element, Point position)
{
element.Arrange(new Rect(position, element.DesiredSize));
}
}
现在,您还可以通过改进 ArrangeElement 方法来考虑子元素HorizontalAlignment
和属性。VerticalAlignment
private void ArrangeElement(UIElement element, Point position)
{
if (element is FrameworkElement)
{
switch (((FrameworkElement)element).HorizontalAlignment)
{
case HorizontalAlignment.Center:
position.X -= element.DesiredSize.Width / 2;
break;
case HorizontalAlignment.Right:
position.X -= element.DesiredSize.Width;
break;
default:
break;
}
switch (((FrameworkElement)element).VerticalAlignment)
{
case VerticalAlignment.Center:
position.Y -= element.DesiredSize.Height / 2;
break;
case VerticalAlignment.Bottom:
position.Y -= element.DesiredSize.Height;
break;
default:
break;
}
}
element.Arrange(new Rect(position, element.DesiredSize));
}