0

在我的应用程序中,我在画布中有一个多边形(4 个点 = 矩形)。我想通过使用鼠标滚轮将多边形缩放一个因子。为此,我使用以下代码:

    double scale = 1.0, factor = 1.01, cX, cY;

    void polygon_MouseWheel(object sender, MouseWheelEventArgs e)
    {
        cX = e.GetPosition(polygon).X;
        cY = e.GetPosition(polygon).Y;

        if (e.Delta > 0) scale *= factor;
        else scale /= factor;

        polygon.RenderTransform = new ScaleTransform(scale, scale, cX, cY);
    }

这很好用,当我将鼠标指针放在多边形中的点 P(假设 P 是靠近多边形左上角的点)并向上或向下滚动时。所以多边形根据那个点放大或缩小。但是当我将鼠标指针移动到另一个点 Q(靠近右下角)并继续放大或缩小时,多边形会向左上角移动一个量 s。似乎 s 的量取决于 P 和 Q 之间的距离。因此,如果 P 和 Q 之间的距离很大,则偏移量很大。

在这种情况下,期望的行为是多边形没有移动,而只是缩放到新的点 Q。

有谁知道,转变的原因是什么?我很感谢任何提示。

示例代码:

<window ...>
    <Grid>
        <Canvas Name="canvas1" Background="LightBlue">
        <Polygon Points="100,100 100,300 300,300 300,100" Name="polygon" Fill="Black" MouseWheel="polygon_MouseWheel"/>
    </Canvas>
    </Grid>
</Window>
public MainWindow()
{
    InitializeComponent();
}

double scale = 1.0, factor = 1.01, cX, cY;

void polygon_MouseWheel(object sender, MouseWheelEventArgs e)
{
    cX = e.GetPosition(polygon).X;
    cY = e.GetPosition(polygon).Y;

    if (e.Delta > 0) scale *= factor;
    else scale /= factor;

    polygon.RenderTransform = new ScaleTransform(scale, scale, cX, cY);
}
4

1 回答 1

0

好的,经过一段时间的尝试,我发现了导致这种行为的原因。UIElement.RenderTransform属性的MSDN 文章说:

渲染转换不会重新生成布局大小或渲染大小信息。渲染变换通常用于为元素设置动画或应用临时效果。例如,元素可能在聚焦或鼠标悬停时缩放,或者在加载时可能会抖动以将注意力吸引到用户界面 (UI) 的该部分。

这意味着,多边形本身,分别是多边形的点,不会被转换。应用 ScaleTransform 时,多边形的点不会改变,并且会保持在 xaml 中设置的状态。然而,转换后的多边形将对鼠标事件做出反应,但鼠标位置映射到原始边界。

示例:让我们采用上面在 xaml 中定义的多边形并将其缩放 1.5 倍。多边形按比例显示,现在它的点似乎具有值 (150,150 150,450 450,450 450,150)。但在内部它仍然具有旧值(100,100 100,300 300,300 300,100)。如果您在缩放的右上角捕捉到鼠标指针的位置,它将是 (300,100) 而不是 (450,150)。

使用鼠标位置作为缩放中心会导致缩放的多边形发生偏移。

一个解决方案是缩放多边形本身的点,而不是使用 ScaleTransform:

void Scale(double factor, double centerX, double centerY)
{
    PointCollection pc = new PointCollection();

    foreach (Point p in polygon.Points)
    {
        Point q = new Point();

        q.X = p.X;
        q.Y = p.Y;

        q.X -= centerX;    // translate
        q.Y -= centerY;

        q.X *= factor;     // scale
        q.Y *= factor;

        q.X += centerX;    // translate back
        q.Y += centerY;

        pc.Add(q);
    }

    polygon.Points = pc;   // polygon is defined in xaml
}

我不确定这是否是正确的方法,但它对我有用。

于 2014-02-13T09:13:02.950 回答