MatrixTransform внутри поведения MatrixTransform - не то, что я ожидал

В настоящее время у меня есть граница, привязанная к MatrixTransform. При прокрутке колесика мыши он в основном масштабирует MatrixTransform. Внутри границы у меня есть прямоугольник, центрированный по горизонтали и вертикали. В то время, когда преобразование границы масштабируется, я устанавливаю преобразование прямоугольника равным инверсии границы. Идея состоит в том, чтобы прямоугольник оставался того же размера и в центре. Мое текущее решение сохранит прямоугольник того же размера, но он постепенно удаляется от центра по мере того, как вы продолжаете увеличивать масштаб. Кажется, что преобразование Rectangle не знает преобразования Border, имеет ли это смысл?

Вот пара изображений, первое - исходное, второе - после двухкратного увеличения (обратите внимание, что прямоугольник остался того же размера, но уже не по центру).

alt text

alt text

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

Вот весь мой код, вы можете вытащить его и запустить, если хотите:

MainPage.xaml

<UserControl x:Class="InvertedZoomTest.MainPage"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:local="clr-namespace:InvertedZoomTest"
mc:Ignorable="d">

<UserControl.DataContext>
    <local:MainPage_ViewModel/>
</UserControl.DataContext>

<Border BorderBrush="Pink" Background="Gray" VerticalAlignment="Center" HorizontalAlignment="Center"  BorderThickness="2" MouseWheel="Border_MouseWheel" Height="100" Width="100" RenderTransform="{Binding MainTransform}">
    <Rectangle x:Name="rectangle" Canvas.Top="43" Canvas.Left="43" Fill="Red" Height="10" Width="10" HorizontalAlignment="Center" VerticalAlignment="Center" RenderTransform="{Binding TextTransform}"/>
</Border>

MainPage.xaml.cs

public partial class MainPage : UserControl
{
    public MainPage()
    {
        InitializeComponent();
    }

    private MainPage_ViewModel viewModel
    {
        get
        {
            return this.DataContext as MainPage_ViewModel;
        }
    }

    private void Border_MouseWheel(object sender, MouseWheelEventArgs e)
    {
        if (e.Delta > 0)
        {
            this.viewModel.ZoomRatio += .1;
        }
        else
        {
            this.viewModel.ZoomRatio -= .1;
        }

        this.viewModel.UpdateTextScale();
    }
}

MainPage_ViewModel.cs

public class MainPage_ViewModel : INotifyPropertyChanged
{
    public MatrixTransform TextTransform
    {
        get { return _textTransform; }
        set
        {
            if (value != _textTransform)
            {
                _textTransform = value;
                OnPropertyChanged("TextTransform");
            }
        }
    }
    private MatrixTransform _textTransform = new MatrixTransform();

    public MatrixTransform MainTransform
    {
        get
        {
            return _mainTransform;
        }
        set
        {
            if (value != _mainTransform)
            {
                _mainTransform = value;
                OnPropertyChanged("MainTransform");
            }
        }
    }
    private MatrixTransform _mainTransform = new MatrixTransform();

    public void UpdateTextScale()
    {
        var scaleX = (double)(ZoomRatio);
        var scaleY = (double)(ZoomRatio);

        Matrix updatedMainTransformMatrix = new Matrix(scaleX, 0, 0, scaleY, 0, 0);
        this.MainTransform.Matrix = updatedMainTransformMatrix;
        OnPropertyChanged("MainTransform");

        this.TextTransform = MainTransform.Inverse as MatrixTransform;
        OnPropertyChanged("TextTransform");
    }

    public double ZoomRatio
    {
        get
        {
            return zoomRatio;
        }
        set
        {
            zoomRatio = value;
            OnPropertyChanged("ZoomRatio");

            UpdateTextScale();
        }
    }
    private double zoomRatio = 1;


    public event PropertyChangedEventHandler PropertyChanged;

    public void OnPropertyChanged(string propertyName)
    {
        if (PropertyChanged != null)
        {
            PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
        }
    }
}

Я делаю что-то не так, из-за чего этот прямоугольник перемещается из центра? Любая помощь будет принята с благодарностью!

ОБНОВЛЕНИЕ Из любопытства я обернул рамку вокруг прямоугольника и сделал привязку элемента к элементу по ширине и высоте. На изображении ниже вы заметите, что преобразование прямоугольника, похоже, имеет начало в левом верхнем углу, имеет ли это смысл?

Новый XAML:

<Border BorderBrush="Pink" Background="Gray" VerticalAlignment="Center" HorizontalAlignment="Center"  BorderThickness="2" MouseWheel="Border_MouseWheel" Height="100" Width="100" RenderTransform="{Binding MainTransform}">
    <Border BorderBrush="Green" BorderThickness="1" Height="{Binding ElementName=rectangle, Path=Height}" Width="{Binding ElementName=rectangle, Path=Width}">
        <Rectangle x:Name="rectangle" Canvas.Top="43" Canvas.Left="43" Fill="Red" Height="10" Width="10" HorizontalAlignment="Center" VerticalAlignment="Center" RenderTransform="{Binding TextTransform}"/>
    </Border>
</Border>

Полученное изображение: alt text


person JSprang    schedule 14.12.2010    source источник


Ответы (1)


Я понял это. Мне просто нужно было установить RenderTransformOrigin моего прямоугольника в центр.

<Border BorderBrush="Pink" Background="Gray" VerticalAlignment="Center" HorizontalAlignment="Center"  BorderThickness="2" MouseWheel="Border_MouseWheel" Height="100" Width="100" RenderTransform="{Binding MainTransform}"> 
<Border BorderBrush="Green" BorderThickness="1" Height="{Binding ElementName=rectangle, Path=Height}" Width="{Binding ElementName=rectangle, Path=Width}"> 
    <Rectangle x:Name="rectangle" Canvas.Top="43" Canvas.Left="43" Fill="Red" Height="10" Width="10" HorizontalAlignment="Center" VerticalAlignment="Center" RenderTransform="{Binding TextTransform}" RenderTransformOrigin=".5,.5"/> 
</Border> 

person JSprang    schedule 14.12.2010