MatrixTransform 内部的 MatrixTransform 行为不是我所期望的

发布于 2024-10-07 12:58:21 字数 4801 浏览 10 评论 0原文

我目前有一个绑定到 MatrixTransform 的 Border。当滚动鼠标滚轮时,它基本上会缩放 MatrixTransform。在边框内部,我有一个水平和垂直居中的矩形。当缩放边框变换时,我将矩形的变换设置为等于边框的反转。 ides 是为了保持矩形大小相同并且位于中心。我当前的解决方案将使矩形保持相同的大小,但随着您不断缩放,它会逐渐远离中心。似乎矩形变换不知道边框变换,这有意义吗?

这是几张图像,第一张是初始图像,第二张是缩放几次后的图像(请注意,矩形保持相同大小,但不再居中)。

替代文本

替代文本

我试图解决的基本想法就像谷歌地图应用程序一样,当你放大时,城市名称大小保持不变。

这是我的所有代码,如果您愿意,您应该能够将其拉入并运行它:

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>

结果图像: 替代文字

I currently have a Border that is bound to a MatrixTransform. When scrolling the mouse wheel, it will basically scale the MatrixTransform. Inside of the border, I have a Rectangle that is centered horizontally and vertically. At the time when the Border transform is scaled, I set the transform of the Rectangle to be equal to the Inverse of the Border. The ides is to keep the rectangle the same size and in the center. My current solution will keep the rectangle the same size, but it gradually moves away from center as you keep zooming. It seems as if the Rectangle transform isn't aware of the Border transform, does that make sense?

Here's a couple images, the first is initial, the second is after zooming a couple times (notice the rectangle stayed the same size, but it's no longer centered).

alt text

alt text

The basic idea that I'm trying to solve is like a Google maps application, when you zoom in, the city name size stays the same.

Here's all of my code, you should be able to pull this in and run it if you'd like:

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

Am I doing something wrong that would make this rectangle move from the center? Any help would be greatly appreciated!

UPDATE
Out of curiousity, I wrapped a border around the rectangle and did an element to element binding on the width & height. You will notice in the image below that the transform on the rectangle seems to have an origin at the top left, does this make sense?

New 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>

Resulting Image:
alt text

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

晚雾 2024-10-14 12:58:21

我明白了这一点。我只需要将矩形的 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> 

I figured this out. I just needed to set the RenderTransformOrigin of my rectangle to the center.

<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> 

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文