我有一个画布控件,我在其中动态添加不同的形状。我通过使用ScaleTransform实现缩放并通过TranslateTransform进行平移。如果我必须放大和缩小而不调整画布中的形状(即调整画布的大小而不用调整孩子的大小),我将如何实现这一目标?
谢谢,
BR,
答案 0 :(得分:0)
以下简单派生的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));
}