Увеличить центр изображения положения мыши - PullRequest
0 голосов
/ 25 февраля 2020

Я следил за наиболее проголосовавшим ответом отсюда. Pan & Zoom Image (тот, что с ZoomBorder.cs).

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

Что я сделал до сих пор:

Создан новый UserControl

<UserControl x:Class="ImageViewer.Controls.ZoomControl"
             xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
             xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
             xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
             xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 
             xmlns:local="clr-namespace:ImageViewer.Controls"
             mc:Ignorable="d" 
             d:DesignHeight="450" d:DesignWidth="800">
    <Border BorderThickness="10" BorderBrush="Red">
        <Image x:Name="RenderingImage" RenderTransformOrigin="0,0" Stretch="None" Source="{Binding}" ClipToBounds="True">
            <Image.LayoutTransform>
                <TransformGroup>
                    <ScaleTransform x:Name="ImageScale" ScaleX="{Binding}" ScaleY="{Binding}"/>
                    <TranslateTransform x:Name="ImageTranslate" X="{Binding}" Y="{Binding}" />
                </TransformGroup>
            </Image.LayoutTransform>
        </Image>
    </Border>
</UserControl>

Добавлена ​​привязка между View-> ViewModel

 public partial class ZoomControl : IViewFor<ZoomControlViewModel>
    {
        public static readonly DependencyProperty ViewModelProperty = DependencyProperty
       .Register(nameof(ViewModel), typeof(ZoomControlViewModel), typeof(ZoomControl), null);
        public ZoomControl()
        {
            InitializeComponent();

            this.DataContextChanged += (sender, args) => ViewModel = DataContext as ZoomControlViewModel;

            this.WhenActivated(cleanup =>
            {
                this.OneWayBind(ViewModel, vm => vm.ImageSource, v => v.RenderingImage.Source).DisposeWith(cleanup);

                this.OneWayBind(ViewModel, vm => vm.ScaleX, v => v.ImageScale.ScaleX).DisposeWith(cleanup);
                this.OneWayBind(ViewModel, vm => vm.ScaleY, v => v.ImageScale.ScaleY).DisposeWith(cleanup);
                this.OneWayBind(ViewModel, vm => vm.TranslateX, v => v.ImageTranslate.X).DisposeWith(cleanup);
                this.OneWayBind(ViewModel, vm => vm.TranslateY, v => v.ImageTranslate.Y).DisposeWith(cleanup);

                RenderingImage.Events().MouseWheel.Select(e => new Tuple<int, Point>(e.Delta, e.GetPosition(RenderingImage))).InvokeCommand(ViewModel.ZoomAction).DisposeWith(cleanup);
            });
        }

        public ZoomControlViewModel ViewModel { get => (ZoomControlViewModel)GetValue(ViewModelProperty); set => SetValue(ViewModelProperty, value); }
        object IViewFor.ViewModel { get => ViewModel; set => ViewModel = (ZoomControlViewModel)value; }
    }

В представлении Модель У меня есть команда масштабирования, реализованная следующим образом.

 public ZoomControlViewModel()
        {
            ZoomAction = ReactiveCommand.Create<Tuple<int, Point>>(z => Zoom(z));
        }

private void Zoom(Tuple<int, Point> deltaArgs)
        {
            int delta = deltaArgs.Item1;
            Point relativePosition = deltaArgs.Item2;

            //var ScaleTransform = GetScaleTransform();
            //var TranslateTransform = GetTranslateTransform();

            double zoom = delta > 0 ? .2 : -.2;
            if (!(delta > 0) && (ScaleX < .4 || ScaleY < .4))
                return;

            double absoluteX;
            double absoluteY;

            absoluteX = relativePosition.X * ScaleX + TranslateX;
            absoluteY = relativePosition.Y * ScaleY + TranslateY;

            ScaleX += zoom;
            ScaleY += zoom;

            TranslateX = absoluteX - relativePosition.X * ScaleX;
            TranslateY = absoluteY - relativePosition.Y * ScaleY;
        }

Теперь мой вопрос. В приведенном выше примере масштабирование работает нормально, но оно не масштабируется до положения мыши, оно увеличивает левый угол изображения.

Насколько мне известно (здесь может быть проблема), изменение TranslateTransform изображения ( TranslateX и TranslateY ) должно увеличить меня до текущая позиция мыши.

Любые советы будут оценены.

...