首页 新闻 搜索 专区 学院

WPF如何改变Canvas中的原点坐标

0
悬赏园豆:100 [已解决问题] 解决于 2015-12-21 14:16

.SetValue(Canvas.LeftProperty, 100.0);
.SetValue(Canvas.TopProperty, 100.0);

用SetValue设置LeftProperty和TopProperty并没有什么效果。

如何才能改变Canvas的坐标系的原点坐标的位置呢?

WPF
西南第一帅的主页 西南第一帅 | 初学一级 | 园豆:76
提问于:2015-11-15 13:24
< >
分享
最佳答案
1

通过ScaleTransform和TranslateTransform

收获园豆:100
jello chen | 大侠五级 |园豆:7101 | 2015-11-15 14:50

C#代码里没找到ScaleTransform和TranslateTransform

西南第一帅 | 园豆:76 (初学一级) | 2015-11-15 15:42

@西南第一帅: 

<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>
View Code
jello chen | 园豆:7101 (大侠五级) | 2015-11-15 16:14

@jello chen: 在后台C#代码中如何实现改变原点坐标呢

西南第一帅 | 园豆:76 (初学一级) | 2015-11-15 17:04

@西南第一帅: 

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;
        }
View Code

写了个相对通用的方法

jello chen | 园豆:7101 (大侠五级) | 2015-11-15 21:33

@jello chen: 我试了下,将Canvas整体位移了,原点坐标好像没变

西南第一帅 | 园豆:76 (初学一级) | 2015-11-16 09:40

@西南第一帅: 嗯,上面的代码都是通过Transform实现的效果,对于canvas本身来说,原点并没有改变。如果你需要真正的改变原点的话,你需要自定义一个canvas,重写其ArrangeOverride方法,如果没思路的话,给我个邮件,我一会儿写个贴下,我的邮箱jello_chen@live.com

jello chen | 园豆:7101 (大侠五级) | 2015-11-16 10:39

@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;
        }
    }
View Code

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>

jello chen | 园豆:7101 (大侠五级) | 2015-11-16 16:02
清除回答草稿
   您需要登录以后才能回答,未注册用户请先注册