Холст LayoutTransform получить фактический масштаб - PullRequest
1 голос
/ 13 октября 2019

Я использую в этом примере (только с преобразованием макета и с прикрепленным поведением вместо внешнего пакета nuget) для увеличения моего холста. Кажется, пока это работает, но я также хочу ограничить примененный коэффициент масштабирования, например, пользователь не может увеличить изображение более чем в 10 раз.

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

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

Дополнительно: как я могу представить этот фактор как свойство зависимости моего присоединенного свойства, чтобы я мог применить к нему привязку из xaml?

Редактировать- добавлен пример кода:

public static class ZoomBehavior
{
    //example from https://stackoverflow.com/questions/46424149/wpf-zoom-canvas-center-on-mouse-position

    #region ZoomFactor
    public static double GetZoomFactor(DependencyObject obj)
    {
        return (double)obj.GetValue(ZoomFactorProperty);
    }
    public static void SetZoomFactor(DependencyObject obj, double value)
    {
        obj.SetValue(ZoomFactorProperty, value);
    }
    // Using a DependencyProperty as the backing store for ZoomFactor.  This enables animation, styling, binding, etc...
    public static readonly DependencyProperty ZoomFactorProperty =
        DependencyProperty.RegisterAttached("ZoomFactor", typeof(double), typeof(ZoomBehavior), new PropertyMetadata(1.05));
    #endregion

    #region ModifierKey       
    public static ModifierKeys? GetModifierKey(DependencyObject obj)
    {
        return (ModifierKeys?)obj.GetValue(ModifierKeyProperty);
    }
    public static void SetModifierKey(DependencyObject obj, ModifierKeys? value)
    {
        obj.SetValue(ModifierKeyProperty, value);
    }
    // Using a DependencyProperty as the backing store for ModifierKey.  This enables animation, styling, binding, etc...
    public static readonly DependencyProperty ModifierKeyProperty =
        DependencyProperty.RegisterAttached("ModifierKey", typeof(ModifierKeys?), typeof(ZoomBehavior), new PropertyMetadata(null));
    #endregion
    public static TransformMode TranformMode { get; set; } = TransformMode.Layout;
    private static Transform _transform;
    private static DesignerCanvas _canvas;

    #region IsZoomable        
    public static bool GetIsZoomable(DependencyObject obj)
    {
        return (bool)obj.GetValue(IsZoomableProperty);
    }
    public static void SetIsZoomable(DependencyObject obj, bool value)
    {
        obj.SetValue(IsZoomableProperty, value);
    }
    // Using a DependencyProperty as the backing store for IsZoomable.  This enables animation, styling, binding, etc...
    public static readonly DependencyProperty IsZoomableProperty =
        DependencyProperty.RegisterAttached(
            "IsZoomable",
            typeof(bool),
            typeof(ZoomBehavior),
            new UIPropertyMetadata(false, OnIsZoomableChanged));
    #endregion

    //#region ScaleMax
    //#region ScaleMin

    private static void OnIsZoomableChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
    {
        _canvas = d as DesignerCanvas;
        if (null == _canvas)
        {
            System.Diagnostics.Debug.Assert(false, "Wrong dependency object type");
            return;
        }
        if ((e.NewValue is bool) == false)
        {
            System.Diagnostics.Debug.Assert(false, "Wrong value type assigned to dependency object");
            return;
        }

        if (true == (bool)e.NewValue)
        {
            _canvas.MouseWheel += Canvas_MouseWheel;
            if (TranformMode == TransformMode.Render)
            {
                _transform = _canvas.RenderTransform = new MatrixTransform();
            }
            else
            {
                _transform = _canvas.LayoutTransform = new MatrixTransform();
            }
        }
        else
        {
            _canvas.MouseWheel -= Canvas_MouseWheel;
        }
    }

    private static void Canvas_MouseWheel(object sender, MouseWheelEventArgs e)
    {
        ModifierKeys? modifierkey = GetModifierKey(sender as DependencyObject);

        if (!modifierkey.HasValue)
        {
            return;
        }

        if((Keyboard.Modifiers & (modifierkey.Value)) == ModifierKeys.None)
        {
            return;
        }

        if (!(_transform is MatrixTransform transform))
        {
            return;
        }

        var pos1 = e.GetPosition(_canvas);
        //double max = GetScaleMax(sender as DependencyObject);
        //double min = GetScaleMin(sender as DependencyObject);

        double zoomfactor = GetZoomFactor(sender as DependencyObject);            
        double scale = (e.Delta < 0) ? zoomfactor : (1 / zoomfactor);
        //scale = (scale > max) ? max : scale;
        //scale = (scale < min) ? min : scale;

        var mat = transform.Matrix;            
        mat.ScaleAt(scale, scale, pos1.X, pos1.Y);
        transform.Matrix = mat;
        e.Handled = true;
    }

    public enum TransformMode
    {
        Layout,
        Render,
    }
}

1 Ответ

1 голос
/ 13 октября 2019

Вы можете взять элементы графики m11 и m22. Преобразовать, чтобы получить масштабные коэффициенты x и y. Вы можете «увеличивать» по-разному в каждом измерении, поэтому вы получаете два фактора.

Но вы никогда не знаете, для чего создан ваш графический объект, они могут на самом деле накладываться друг на друга, лучше выотследите любую операцию масштабирования, которую вы выполняете, по другой переменной.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...