开发者

WPF Render Transform Behaving Weird

开发者 https://www.devze.com 2023-03-17 14:48 出处:网络
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 pla

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 se开发者_StackOverflowt. 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


If anyone is looking for an answer to this, because of deadlines, I had to write a workaround by having the user pan with the right mouse button and zoom with the mouse wheel. This way zooming always happens around the center of the image, so the controls are always lined up. I'm still looking for answers to the original question though if anyone can figure it out

Thanks,

Max


I'm not sure what's wrong with your transform, but have you considered an alternate approach? For example, you might want to add a transparent canvas set to stay at the same size as the image, z-order above the image (explicitly set or just put the Canvas element just after the image element). Then you can just use Canvas.SetLeft and Canvas.SetTop to place the user control where the user clicked, and to move it around. A lot easier than using a transform.

0

精彩评论

暂无评论...
验证码 换一张
取 消