MatrixTransform внутри поведения MatrixTransform не то, что я ожидал - PullRequest
0 голосов
/ 14 декабря 2010

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

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

alt text

alt text

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

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

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

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

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

Новый 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

1 Ответ

0 голосов
/ 14 декабря 2010

Я понял это. Мне просто нужно было установить 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> 

...