0

I am experiencing a weird problem with a render transform in WPF. The project I'm working on needs to display a clicked user point over an image. When the user clicks a point, a custom control is placed at the location of their click. The image should then be able to be scaled around any point using the mouse wheel, and the custom control should be translated (not scaled) to the correct location.

To do this, I follow the MouseWheel event as follows:

private void MapPositioner_MouseWheel(object sender, MouseWheelEventArgs e)
{   
    Point location = Mouse.GetPosition(MainWindow.Instance.imageMap);

    MainWindow.Instance.imageMap.RenderTransform = null;

    ScaleTransform st = new ScaleTransform(scale + (e.Delta < 0 ? -0.2 : 0.2), scale += (e.Delta < 0 ? -0.2 : 0.2));
    st.CenterX = location.X;
    st.CenterY = location.Y;


    TransformGroup tg = new TransformGroup();
    tg.Children.Add(st);
    //tg.Children.Add(tt);

    MainWindow.Instance.imageMap.RenderTransform = tg;

    if (scale <= 1)
    {
        MainWindow.Instance.imageMap.RenderTransform = null;
    }

    if (TransformationChanged != null)
        TransformationChanged();
}

Then, I implemented an event handler in the custom control for the TransformationChanged event seen at the end of the above code block as follows:

private void Instance_TransformationChanged()
    {
        //check image coords
        //
        if (MainWindow.Instance.imageMap.RenderTransform != null)
        {
            if (MainWindow.Instance.imageMap.RenderTransform != Transform.Identity)
            {
                Transform st = MainWindow.Instance.imageMap.RenderTransform;

                Point image = MainWindow.VideoOverlayCanvas.TransformToVisual(MainWindow.Instance.MapImage).Transform(loc2);

                Point trans = st.Transform(image);

                Point final = MainWindow.Instance.MapImage.TransformToVisual(MainWindow.VideoOverlayCanvas).Transform(trans);

               // selected = anchor2;
               // final = ClipToOverlay(final);
               // selected = null;

                connector.X2 = final.X;
                connector.Y2 = final.Y;

                Canvas.SetLeft(anchor2, final.X);
                Canvas.SetTop(anchor2, final.Y);                    
            }
        }
        else
        {
            connector.X2 = loc2.X;
            connector.Y2 = loc2.Y;

            Canvas.SetLeft(anchor2, loc2.X);
            Canvas.SetTop(anchor2, loc2.Y);
        }
    }

This way, I can ensure that the custom control's position is updated only after the new transform is set. Note that since I am applying the transform to the point, there is no scaling done to the control, the effect is that it is translated to the point it should. This works fine as long as the user is only scaling around one point. If they change that point, it doesnt work. Here are some images that show the problem:

User clicks a point

user zooms out, what happened here?

after zooming out (all the way out in this case) it looks ok

I've been messing with this for about two days now, so I apologize if my code looks messy. I know this is a pretty obscure question so any help would be appreciated.

Thanks, Max

4

2 回答 2

1

如果有人正在寻找这个问题的答案,由于截止日期,我不得不编写一个解决方法,让用户用鼠标右键平移并用鼠标滚轮缩放。这种方式缩放总是围绕图像的中心进行,所以控件总是对齐的。我仍在寻找原始问题的答案,但如果有人能弄清楚的话

谢谢,

最大限度

于 2011-07-07T13:35:49.860 回答
0

我不确定您的转换有什么问题,但是您是否考虑过另一种方法?例如,您可能希望添加一个透明画布集以保持与图像相同的大小、图像上方的 z 顺序(显式设置或仅将 Canvas 元素放在图像元素之后)。然后,您可以使用 Canvas.SetLeft 和 Canvas.SetTop 将用户控件放置在用户单击的位置,并移动它。比使用转换容易得多。

于 2011-07-06T19:59:48.683 回答