c#画布缩放功能问题?使用矩阵变换放大到某个点后无法缩小到原始位置

时间:2016-09-25 09:12:59

标签: c# wpf canvas zoom mousewheel

我尝试使用矩阵变换在c#中实现画布缩放功能。我可以放大到一个特定点,但在缩小到原始比例(我已经限制为原始比例)时,画布的位置会发生变化(窗外)。我希望它缩小到原来的位置。有人可以帮忙吗?

请找到以下代码:

<ScrollViewer Name="C1_S" Grid.Row="0" HorizontalScrollBarVisibility="Auto" VerticalScrollBarVisibility="Auto" VerticalAlignment="Bottom"  Grid.ColumnSpan="2" >
                    <Canvas Name="canvas_core0" Grid.Row="1" HorizontalAlignment="Right" VerticalAlignment="Bottom" Height="600" Width="1000000" MouseWheel="Canvas_MouseWheel" ClipToBounds="True" >
                        <Canvas.Background>
                            <DrawingBrush TileMode="Tile" Viewport="0,20,40,40" ViewportUnits="Absolute">
                                <DrawingBrush.Drawing>
                                    <GeometryDrawing>
                                        <GeometryDrawing.Geometry>
                                            <RectangleGeometry Rect="0,0,50,50"/>
                                        </GeometryDrawing.Geometry>
                                        <GeometryDrawing.Pen>
                                            <Pen Brush="Gray" Thickness=".1"/>
                                        </GeometryDrawing.Pen>
                                    </GeometryDrawing>
                                </DrawingBrush.Drawing>
                            </DrawingBrush>
                        </Canvas.Background>
                        <Canvas.RenderTransform>
                            <MatrixTransform/>
                        </Canvas.RenderTransform>
                    </Canvas>
                </ScrollViewer>

C#代码:`

        private void Canvas_MouseWheel(object sender, MouseWheelEventArgs e)
    {
        var element = sender as UIElement;
        var position = e.GetPosition(element);
        if(e.Delta>0)
        {
            previousposition = position;
        }
        var transform = element.RenderTransform as MatrixTransform;
        var matrix = transform.Matrix;
        scrollcountprevious = scrollcountcurrent;
        scrollcountcurrent = scrollcountcurrent + e.Delta;
       // var scale1 = scrollcountcurrent > scrollcountprevious ? 1.1 : scrollcountcurrent <scrollcountprevious0 ? 1.0 : (1.0 / 1.1); // choose appropriate scaling factor
        var scale1=1.0;
        if (scrollcountcurrent > scrollcountprevious)
        {
            scale1 = 1.1;
            matrix.ScaleAtPrepend(scale1, scale1, position.X, position.Y);
            transform.Matrix = matrix;
        }
        else if (scrollcountcurrent < scrollcountprevious&&scrollcountcurrent>=0)
        {
            scale1 = 1 / 1.1;
             matrix.ScaleAtPrepend(scale1, scale1, previousposition.X, previousposition.Y);
        transform.Matrix = matrix;

        }
        else
        {
            scale1 = 1;
            scrollcountcurrent = 0;
            matrix.ScaleAtPrepend(scale1, scale1, previousposition.X, previousposition.Y);
            transform.Matrix = matrix;
        }

    }

1 个答案:

答案 0 :(得分:0)

不确定我是否理解您正在努力实现的目标。此外,在ScrollViewer中使用Canvas可能会搞砸。

但是这个MouseWheel处理程序可能会做你想要的:

private double scale = 1;

private void Canvas_MouseWheel(object sender, MouseWheelEventArgs e)
{
    var element = (UIElement)sender;
    var position = e.GetPosition(element);
    var matrix = Matrix.Identity;

    scale = Math.Max(e.Delta > 0 ? scale * 1.1 : scale / 1.1, 1.0);
    matrix.ScaleAt(scale, scale, position.X, position.Y);

    ((MatrixTransform)element.RenderTransform).Matrix = matrix;
}

为了在ScrollViewer中缩放Canvas的实际大小,请缩放其LayoutTransform而不是RenderTransform

<Canvas.LayoutTransform>
    <MatrixTransform/>
</Canvas.LayoutTransform>

private void Canvas_MouseWheel(object sender, MouseWheelEventArgs e)
{
    var element = (FrameworkElement)sender;
    var position = e.GetPosition(element);
    var matrix = Matrix.Identity;

    scale = Math.Max(e.Delta > 0 ? scale * 1.1 : scale / 1.1, 1.0);
    matrix.ScaleAt(scale, scale, position.X, position.Y);

    ((MatrixTransform)element.LayoutTransform).Matrix = matrix;
}