缩放&平移问题翻译/ ScaleTransform WPF

时间:2013-03-27 18:48:38

标签: c# wpf resize zoom

我有一个画布控件,我在其中动态添加不同的形状。我通过使用ScaleTransform实现缩放并通过TranslateTransform进行平移。如果我必须放大和缩小而不调整画布中的形状(即调整画布的大小而不用调整孩子的大小),我将如何实现这一目标?

谢谢,

BR,

1 个答案:

答案 0 :(得分:0)

以下简单派生的Canvas会将其子元素排列在由Canvas.LeftCanvas.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方法来考虑子元素的HorizontalAlignmentVerticalAlignment属性。

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));
}