C# WPF中的奇异尺度问题

C# WPF中的奇异尺度问题,c#,wpf,.net-4.0,C#,Wpf,.net 4.0,我有一张画布,我在上面放了一些东西,然后缩放它。但是,当您运行缩放时,它们不是从它们应该的点开始的,比如,如果您从一个原点稍微缩放它,然后从另一个原点缩放,那么第二个原点的行为就好像它以一种非常奇怪的方式被偏移一样,而不是按照预期的方式(以及第一个原点的行为)。我一直在使用ths代码执行缩放: foreach (UIElement element in canvas1.Children) { Point p = e.MouseDevice.

我有一张画布,我在上面放了一些东西,然后缩放它。但是,当您运行缩放时,它们不是从它们应该的点开始的,比如,如果您从一个原点稍微缩放它,然后从另一个原点缩放,那么第二个原点的行为就好像它以一种非常奇怪的方式被偏移一样,而不是按照预期的方式(以及第一个原点的行为)。我一直在使用ths代码执行缩放:

        foreach (UIElement element in canvas1.Children)
        {
            Point p = e.MouseDevice.GetPosition(element);
            Matrix m = element.RenderTransform.Value;
            if (e.Delta > 0)
                m.ScaleAt(1.1, 1.1, p.X, p.Y);
            else
                m.ScaleAt(1 / 1.1, 1 / 1.1, p.X, p.Y);
            element.RenderTransform = new MatrixTransform(m);
        }
到底发生了什么事


我意识到我最初的问题文本并没有那么清晰。我从鼠标原点开始缩放,因此您可以将鼠标移动到我的示例文本对象对的左侧,滚动滚轮,它们可以放大或缩小,并以完美的方式在屏幕上移动。但是如果你把鼠标移到物体的另一端,并尝试滚动,那么它们就好像中间的鼠标——也就是说,它们在不移动屏幕的情况下放大和缩小。

< P>当你使用SCALLATE创建一个转换时,你也在创建一个翻译。例如,如果鼠标指针位于元素左侧100像素处,则将其缩放1.1,并向右移动10像素。下次代码运行时,您也将缩放该转换,因此除了新的转换之外,还要将其向右移动1个像素

一种解决方案是在应用比例尺之前将平移与上一个矩阵分开,然后将其添加回末尾:

foreach (UIElement element in canvas1.Children)
{
    Point p = e.MouseDevice.GetPosition(element);
    Matrix m = element.RenderTransform.Value;
    Matrix m2 = m;
    m2.Translate(-m.OffsetX, -m.OffsetY);
    if (e.Delta > 0)
        m2.ScaleAt(1.1, 1.1, p.X, p.Y);
    else
        m2.ScaleAt(1 / 1.1, 1 / 1.1, p.X, p.Y);
    m2.Translate(m.OffsetX, m.OffsetY);
    element.RenderTransform = new MatrixTransform(m2);
}
类似的选项是始终从RenderTransform中删除缩放,并在Canvas.Left和Canvas.Top中对其进行编码:

foreach (UIElement element in canvas1.Children)
{
    Point p = e.MouseDevice.GetPosition(element);
    Matrix m = element.RenderTransform.Value;
    if (e.Delta > 0)
        m.ScaleAt(1.1, 1.1, p.X, p.Y);
    else
        m.ScaleAt(1 / 1.1, 1 / 1.1, p.X, p.Y);
    Canvas.SetLeft(element, Canvas.GetLeft(element) + m.OffsetX);
    Canvas.SetTop(element, Canvas.GetTop(element) + m.OffsetY);
    m.Translate(-m.OffsetX, -m.OffsetY);
    element.RenderTransform = new MatrixTransform(m);
}

更新:事实上,我想我错过了更大的相关效应。因为您是在旧的刻度之后应用新的刻度,所以p.X和p.Y的转换在不应该被缩放时被缩放。当比例很大时,这将是一个很大的错误(而我上面提到的错误总是10%的错误)

首先尝试使用应用新转换:

foreach (UIElement element in canvas1.Children)
{
    Point p = e.MouseDevice.GetPosition(element);
    Matrix m = element.RenderTransform.Value;
    if (e.Delta > 0)
        m.ScaleAtPrepend(1.1, 1.1, p.X, p.Y);
    else
        m.ScaleAtPrepend(1 / 1.1, 1 / 1.1, p.X, p.Y);
    Canvas.SetLeft(element, Canvas.GetLeft(element) + m.OffsetX);
    Canvas.SetTop(element, Canvas.GetTop(element) + m.OffsetY);
    m.Translate(-m.OffsetX, -m.OffsetY);
    element.RenderTransform = new MatrixTransform(m);
}

当您移入时,这两个元素会蠕动在一起,如果您缩小,则不会分离。从概念上讲,我理解您的观点,认为您的代码应该可以工作,但在我的测试床上,它会产生更奇怪的结果。两人表现出相同的行为。谢谢,这就是温拉!现在无法观察到任何意外行为。