【问题标题】:WPF: Access transformed Canvas coordinates in code behindWPF:在后面的代码中访问转换后的 Canvas 坐标
【发布时间】:2021-08-16 19:43:11
【问题描述】:

在 WPF 中有没有办法在代码隐藏文件中访问画布面板(在 xaml 文件中创建)的 ScaleTransform 参数?

用例示例:

我想在一个缩放的画布内放置一个项目列表,如下所示:

<ItemsControl MouseMove="Control_MouseMove">
    <ItemsControl.ItemsPanel>
            <ItemsPanelTemplate>
                    <Canvas>
                        <Canvas.RenderTransform>
                              <TransformGroup>
                                   <ScaleTransform>
                                        <ScaleTransform.ScaleX />
                                   </ScaleTransform>
                              </TransformGroup>
                        </Canvas.RenderTransform>
                    </Canvas>
             </ItemsPanelTemplate>
     </ItemsControl.ItemsPanel>
</ItemsControl>

我还想在鼠标悬停时通过弹出窗口显示我的项目在画布内的当前位置。我目前正在尝试这种方式:

public void Control_MouseMove(object sender, MouseEventArgs e) {
    if (!this.Popup.IsOpen)
        this.Popup.IsOpen = true;
    var mousePosition = e.GetPosition(this.SwLane);
    this.Popup.HorizontalOffset = mousePosition.X + 10;
    this.Popup.VerticalOffset = mousePosition.Y - 20;
    this.PopupContent.Text = System.Convert.ToString(mousePosition.X);
}

我得到的是 Popup 内的画布 X 坐标(这对我来说很有意义)。但是,我想显示画布的比例转换“坐标”。

有没有办法访问 Code Behind 中的 ScaleTransform 参数,以便我可以可视化转换后的项目位置?还是我应该以不同的方式来做?谢谢。

【问题讨论】:

    标签: c# wpf xaml canvas rendertransform


    【解决方案1】:

    您可以设置一个 OnInitialized 处理程序,在其中在代码隐藏中构建您的转换,将其组成部分 ScaleTransform 保存为私有属性,然后在您的窗口初始化后将其分配给那里

    大致是这样的:

    <Window x:Class="WpfApp4.MainWindow"
            xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
            xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
            Background="White"
            MouseLeftButtonDown="MainWindow_OnMouseLeftButtonDown"
            Initialized="MainWindow_OnInitialized"
            Title="MainWindow" Height="450" Width="800">
        <Grid>
            <ItemsControl x:Name="MyItems" >
                <ItemsControl.ItemsPanel>
                    <ItemsPanelTemplate>
                        <Canvas />
                    </ItemsPanelTemplate>
                </ItemsControl.ItemsPanel>
            </ItemsControl>
    
            <Rectangle Width="100" Height="200" Stroke="Red" StrokeThickness="5"/>
        </Grid>
    </Window>
    
    
    public partial class MainWindow : Window
    {
        public MainWindow()
        {
            InitializeComponent();
        }
    
        private TransformGroup MyTransform { get; set; }
        private ScaleTransform SceneScale { get; set; }
    
    
        private void MainWindow_OnInitialized(object? sender, EventArgs e)
        {
            MyTransform = new TransformGroup();
            SceneScale = new ScaleTransform(1.0, 1.0, 0, 0);
            MyTransform.Children.Add(SceneScale);
            MyItems.RenderTransform = MyTransform;
        }
    }
    

    现在您可以添加一个 MouseLeftButtonDown 处理程序来缩放事物,例如:

        private void MainWindow_OnMouseLeftButtonDown(object sender, MouseButtonEventArgs e)
        {
            SceneScale.ScaleX *= 1.1;
            SceneScale.ScaleY *= 1.1;
        }
    

    对于坐标事物,将当前坐标暴露为属性。当鼠标移动时更新它们。将 UI 绑定到它们

    如果你把它全部打包在一个控件中,这可能会更好

    【讨论】:

    • 我喜欢这个主意,谢谢!对于比例变换,我需要来自我的 DataContext 的值。你能告诉我如何将它传递给背后的代码吗?
    • 您已经可以访问它了。我的示例中的 MainWindow 类是一个 FrameworkElement,这意味着它有一个 DataContext 属性。无论您在应用中使用什么,都一样
    • 现在我明白了。我错过了我可以使用反射从数据上下文中检索属性。谢谢你的努力;我接受了它,因为具有比例属性也有帮助。
    猜你喜欢
    • 1970-01-01
    • 2021-01-13
    • 1970-01-01
    • 2017-02-09
    • 1970-01-01
    • 2011-12-22
    • 2011-10-29
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多