.SetValue(Canvas.LeftProperty, 100.0);
.SetValue(Canvas.TopProperty, 100.0);
用SetValue设置LeftProperty和TopProperty并没有什么效果。
如何才能改变Canvas的坐标系的原点坐标的位置呢?
通过ScaleTransform和TranslateTransform
C#代码里没找到ScaleTransform和TranslateTransform
@西南第一帅:
<Canvas > <Canvas.RenderTransform> <TransformGroup> <ScaleTransform ScaleX="2" ScaleY="2"/> <TranslateTransform X="{Binding ActualWidth, RelativeSource={RelativeSource AncestorType=Canvas}}" Y="{Binding ActualHeight, RelativeSource={RelativeSource AncestorType=Canvas}}"/> <ScaleTransform ScaleX="0.5" ScaleY="0.5"/> </TransformGroup> </Canvas.RenderTransform> <Button Content="Button"> </Button> </Canvas>
@jello chen: 在后台C#代码中如何实现改变原点坐标呢
@西南第一帅:
private void SetCanvasOrigin(Point point) { var transformGroup = new TransformGroup(); var scaleUpTransform = new ScaleTransform(); var translateTransform = new TranslateTransform(); var scaleDownTransform = new ScaleTransform(); var relativeSource = new RelativeSource { AncestorType = typeof(Canvas) }; if (point.X > 0) { var xScale = Canvas.ActualWidth / point.X; scaleUpTransform.ScaleX = xScale; var xBinding = new Binding("ActualWidth"); xBinding.RelativeSource = relativeSource; BindingOperations.SetBinding(translateTransform, TranslateTransform.XProperty, xBinding); scaleDownTransform.ScaleX = 1/xScale; } if (point.Y > 0) { var yScale = Canvas.ActualHeight / point.Y; scaleUpTransform.ScaleY = yScale; var yBinding = new Binding("ActualHeight"); yBinding.RelativeSource = relativeSource; BindingOperations.SetBinding(translateTransform, TranslateTransform.YProperty, yBinding); scaleDownTransform.ScaleY = 1/yScale; } transformGroup.Children.Add(scaleUpTransform); transformGroup.Children.Add(translateTransform); transformGroup.Children.Add(scaleDownTransform); this.Canvas.RenderTransform = transformGroup; }
写了个相对通用的方法
@jello chen: 我试了下,将Canvas整体位移了,原点坐标好像没变
@西南第一帅: 嗯,上面的代码都是通过Transform实现的效果,对于canvas本身来说,原点并没有改变。如果你需要真正的改变原点的话,你需要自定义一个canvas,重写其ArrangeOverride方法,如果没思路的话,给我个邮件,我一会儿写个贴下,我的邮箱jello_chen@live.com
@jello chen:
1.自定义控件代码:
/// <summary> /// 自定义坐标系Canvas /// </summary> public class CoordinateCanvas : Canvas { /// <summary> /// 原点X坐标 /// </summary> public double OriginX { get { return (double)GetValue(OriginXProperty); } set { SetValue(OriginXProperty, value); } } // Using a DependencyProperty as the backing store for OriginX. This enables animation, styling, binding, etc... public static readonly DependencyProperty OriginXProperty = DependencyProperty.Register("OriginX", typeof(double), typeof(CoordinateCanvas), new PropertyMetadata(0.0, OnOriginPropertyChanged)); private static void OnOriginPropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e) { var uiElement = d as UIElement; if (uiElement != null) { uiElement.InvalidateArrange(); } } /// <summary> /// 原点Y坐标 /// </summary> public double OriginY { get { return (double)GetValue(OriginYProperty); } set { SetValue(OriginYProperty, value); } } // Using a DependencyProperty as the backing store for OriginY. This enables animation, styling, binding, etc... public static readonly DependencyProperty OriginYProperty = DependencyProperty.Register("OriginY", typeof(double), typeof(CoordinateCanvas), new PropertyMetadata(0.0, OnOriginPropertyChanged)); protected override Size ArrangeOverride(Size arrangeSize) { Point originalPoint = new Point(); if (OriginX > 0 && OriginX <= arrangeSize.Width) originalPoint.X = OriginX; if (OriginY > 0 && OriginY <= arrangeSize.Height) originalPoint.Y = OriginY; foreach (UIElement element in InternalChildren) { if (element == null) continue; double x = 0.0; double y = 0.0; double left = GetLeft(element); if (!double.IsNaN(left)) { x = left; } double top = GetTop(element); if (!double.IsNaN(top)) { y = top; } element.Arrange(new Rect(new Point(originalPoint.X + x, originalPoint.Y + y), element.DesiredSize)); } return arrangeSize; } }
2.xaml调用:
<local:CoordinateCanvas x:Name="Canvas" OriginX="100" OriginY="100">
<Button Content="click" x:Name="btn" local:CoordinateCanvas.Left ="-30" local:CoordinateCanvas.Top="-30">
</Button>
</local:CoordinateCanvas>