如何在 WPF 中更改画布的位置?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/33750702/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-13 13:32:25  来源:igfitidea点击:

How can change position of canvas in WPF?

c#wpfxamlcanvas

提问by Evgeni Velikov

How can change runtime position of a canvas in which dynamically I added controls like (labels, lines)?

如何更改画布的运行时位置,其中动态添加了(标签、线条)等控件?

I can zoom canvas with all controls but I can't move in another position with MouseMove, MouseUp, MouseDown.

我可以使用所有控件缩放画布,但我无法使用 MouseMove、MouseUp、MouseDown 在其他位置移动。

<Canvas Name="canvas" Width="1000" Height="400"
            Margin="100 0 0 50"
            Background="White"
            VerticalAlignment="Bottom"
            HorizontalAlignment="Center"
            MouseWheel="Canvas_MouseWheel"
            MouseMove="Canvas_MouseMove"
            MouseUp="Canvas_MouseUp"
            MouseDown="Canvas_MouseDown">
        <Canvas.RenderTransform>
            <ScaleTransform x:Name="st" />
        </Canvas.RenderTransform>
    </Canvas>

I find this code in internet but for my case is not working

我在互联网上找到了这段代码,但对我来说不起作用

bool activated;
    Point point;

    private void Canvas_MouseDown(object sender, MouseButtonEventArgs e)
    {
        activated = true;
        point = Mouse.GetPosition(canvas);
        Mouse.Capture(canvas);
    }

    private void Canvas_MouseMove(object sender, MouseEventArgs e)
    {
        if (activated)
        {
            double top = Canvas.GetTop(canGraph) + Mouse.GetPosition(canvas).Y - point.Y;
            Canvas.SetTop(canvas, top);
            double left = Canvas.GetLeft(canvas) + Mouse.GetPosition(canvas).X - point.X;
            Canvas.SetLeft(canvas, left);
            point = Mouse.GetPosition(canvas);
        }
    }

    private void Canvas_MouseUp(object sender, MouseButtonEventArgs e)
    {
        activated = false;
        Mouse.Capture(null);
    }

回答by kirotab

Edit - The previous solution that I provided was not going to work after the first move of the element without more code so here's a better one

编辑 - 我提供的先前解决方案在没有更多代码的情况下第一次移动元素后将无法工作,所以这里有一个更好的解决方案

In order to be working correctly the canvas element have to be aligned to the coordinate system of it's parent, which we achieve as we put the canvas in top left corner, if you don't put it there you have to calculate the difference yourselve.

为了正确工作,画布元素必须与其父元素的坐标系对齐,这是我们将画布放在左上角时实现的,如果你不把它放在那里,你必须自己计算差异。

Code behind

背后的代码

private void Canvas_MouseDown(object sender, MouseButtonEventArgs e)
    {
        canvas.CaptureMouse();
    }

    Stopwatch sw = new Stopwatch();
    private void Canvas_MouseMove(object sender, MouseEventArgs e)
    {
        if (canvas.IsMouseCaptured)
        {
            translate.X = e.GetPosition(container).X;
            translate.Y = e.GetPosition(container).Y;
        }
    }

    private void Canvas_MouseUp(object sender, MouseButtonEventArgs e)
    {
        canvas.ReleaseMouseCapture();
    }

XAML

XAML

<Grid Background="Green" x:Name="container">
    <Canvas Name="canvas" Width="100" Height="100"
        Margin="0 0 0 0"
        Background="Purple"
        VerticalAlignment="Top"
        HorizontalAlignment="Left"
        MouseMove="Canvas_MouseMove"

        MouseDown="Canvas_MouseDown">
        <StackPanel Background="White">

        <TextBlock >asdasda</TextBlock>
        <TextBlock >cccc</TextBlock>
        <TextBlock >aaaaa</TextBlock>
        <TextBlock >bbbb</TextBlock>
        </StackPanel>
    <Canvas.RenderTransform>
            <TransformGroup>
                <ScaleTransform x:Name="st" />
                <TranslateTransform x:Name="translate" />
            </TransformGroup>
        </Canvas.RenderTransform>
</Canvas>
</Grid>


Original answer

原答案



XAML

XAML

I'd do something like this:

我会做这样的事情:

  • Add a translate transform and to keep you previous transform put it in a group

  • Use translate transform in order to move the canvas with positions from the mouse events

  • For starting point of your translations you can use coordinates in the container

  • 添加一个翻译变换并保持你以前的变换把它放在一个组中

  • 使用平移变换以移动具有鼠标事件位置的画布

  • 对于翻译的起点,您可以使用容器中的坐标

Code behind:

后面的代码:

bool activated;
    Point point;

    private void Canvas_MouseDown(object sender, MouseButtonEventArgs e)
    {
        activated = true;
        point = e.GetPosition(container);
    }

    private void Canvas_MouseMove(object sender, MouseEventArgs e)
    {
        if (activated)
        {
            translate.X = e.GetPosition(container).X - point.X;
            translate.Y = e.GetPosition(container).Y - point.Y;
        }
    }

    private void Canvas_MouseUp(object sender, MouseButtonEventArgs e)
    {
        activated = false;
    }

XAML

XAML

<Canvas Name="canvas" Width="100" Height="100"
        Margin="0 0 0 0"
        Background="Purple"
        VerticalAlignment="Stretch"
        HorizontalAlignment="Stretch"
        MouseMove="Canvas_MouseMove"
        MouseUp="Canvas_MouseUp"
        MouseDown="Canvas_MouseDown">
    <Canvas.RenderTransform>
            <TransformGroup>
                <ScaleTransform x:Name="st" />
                <TranslateTransform x:Name="translate" />
            </TransformGroup>
        </Canvas.RenderTransform>
</Canvas>
</Grid>