WPF Render Transform ведет себя странно - PullRequest
0 голосов
/ 06 июля 2011

У меня странная проблема с преобразованием рендеринга в WPF.Проект, над которым я работаю, должен отображать точку клика пользователя над изображением.Когда пользователь щелкает точку, пользовательский элемент управления размещается в месте его щелчка.Затем изображение можно будет масштабировать вокруг любой точки с помощью колесика мыши, а пользовательский элемент управления должен быть переведен (не масштабирован) в правильное местоположение.

Для этого я следую за событием MouseWheel следующим образом:

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();
}

Затем я реализовал обработчик событий в пользовательском элементе управления для события TransformationChanged, видимого в концеприведенный выше блок кода выглядит следующим образом:

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);
        }
    }

Таким образом, я могу гарантировать, что позиция пользовательского элемента управления обновляется только после установки нового преобразования.Обратите внимание, что, поскольку я применяю преобразование к точке, масштабирование для элемента управления не выполняется, эффект заключается в том, что оно переводится в нужную точку.Это прекрасно работает, пока пользователь масштабирует только одну точку.Если они меняют эту точку, это не работает.Вот некоторые изображения, которые показывают проблему:

Пользователь щелкает точку

пользователь уменьшает масштаб, что здесь произошло?

после уменьшения (полностью в этом случае) все выглядит нормально

Я вот уже два дня возлюсь с этим, поэтому прошу прощения, если мой код выглядит грязно.Я знаю, что это довольно неясный вопрос, поэтому любая помощь будет принята с благодарностью.

Спасибо, Макс

Ответы [ 2 ]

1 голос
/ 07 июля 2011

Если кто-то ищет ответ на этот вопрос из-за крайних сроков, мне пришлось написать обходной путь, заставив пользователя перемещаться по правой кнопке мыши и масштабировать колесом мыши.Таким образом, масштабирование всегда происходит вокруг центра изображения, поэтому элементы управления всегда выровнены.Я все еще ищу ответы на оригинальный вопрос, хотя, если кто-нибудь может понять это

Спасибо,

Макс

0 голосов
/ 06 июля 2011

Я не уверен, что не так с вашим преобразованием, но вы рассматривали альтернативный подход? Например, вы можете добавить прозрачный холст, установленный таким же размером, как изображение, в z-порядке над изображением (явно установите или просто поместите элемент Canvas сразу после элемента изображения). Затем вы можете просто использовать Canvas.SetLeft и Canvas.SetTop, чтобы разместить пользовательский элемент управления там, где пользователь щелкнул, и переместить его. Намного проще, чем с помощью преобразования.

...