【问题标题】:XAML: transform position on panel without transforming the elementXAML:在面板上变换位置而不变换元素
【发布时间】:2014-07-01 02:23:30
【问题描述】:

我想在Canvas 上定位元素(在我的情况下,它是几个图形和文本元素)并通过Transform转换这些元素的位置,但不是 转换元素本身Transform 需要动态更改,例如调整大小或更改旋转角度。我不想触碰元素,只想触碰我绑定的变换。

我现在拥有的:

<UserControl x:Class="IDEAUserInterfaces.StationaryUI.UserControl1"
             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" 
             mc:Ignorable="d" 
             d:DesignHeight="300" d:DesignWidth="300">
    <UserControl.Resources>
        <TranslateTransform x:Key="translate" X="10" Y="10"/>
        <ScaleTransform x:Key="scale" ScaleX="0.8" ScaleY="1.3"/>
        <RotateTransform x:Key="rotate" Angle="30"/>
        <TransformGroup x:Key="group">
            <StaticResource ResourceKey="translate"/>
            <StaticResource ResourceKey="scale"/>
            <StaticResource ResourceKey="rotate"/>
        </TransformGroup>
    </UserControl.Resources>
    <Grid>
        <Canvas Width="100" Height="100">
            <Canvas Name="elementCanvas" Canvas.Top="15" Canvas.Left="20">
                <Path Stroke="Green" StrokeThickness="1">
                    <Path.Data>
                        <EllipseGeometry RadiusX="5" RadiusY="5" Center="0,0" Transform="{Binding StaticResource group}"/>
                    </Path.Data>
                </Path>
                <TextBlock Text="Text" Canvas.Left="10" FontSize="10"/>
            </Canvas>
        </Canvas>
    </Grid>
</UserControl>

显然 elementCanvas 的位置设置了包含的图形和文本的位置。在EllipseGeometry 上设置Transform 会转换整个几何图形。我发现无法在 XAML 中转换 Point,例如 EllipseGeomtry 的 Center-property。这仍然不会改变TextBlock 的位置。

我认为,转换 Canvas.TopCanvas.Left 就足够了,但是如何做到这一点呢?

【问题讨论】:

    标签: c# wpf xaml


    【解决方案1】:

    如果您不想Transform UI 元素,那么不要在它们上使用任何类型的Transform 对象。如果您在Canvas 上对元素的位置进行数据绑定,那么您只需更新相关元素的相关属性,它们就会相应地移动:

    <Style x:Key="ElementStyle">
        <Setter Property="Canvas.Left" Value="{Binding Left}" />
        <Setter Property="Canvas.Top" Value="{Binding Top}" />
    </Style>
    
    <ItemsControl ItemsSource="{Binding YourElements}"
        ItemsContainerStyle="{StaticResource ElementStyle}">
        <ItemsControl.ItemsPanel>
            <ItemsPanelTemplate>
                <Canvas />
            </ItemsPanelTemplate>
        </ItemsControl.ItemsPanel>
    </ItemsControl>
    

    然后要更新他们的位置,你可以这样做:

    element.Left = newPosition.X;
    element.Top = newPosition.Y;
    

    为了清楚起见,您必须在代表 UI 元素的数据类中声明 LeftTop 属性。您可以阅读 MSDN 上的 Data Binding Overview 页面,了解有关数据绑定的更多信息。

    【讨论】:

    • 这正是我想要避免的:遍历每个元素并手动更改位置。 Transform 应该是我唯一需要更改的内容...更新了问题以使其更清楚。
    • 我认为转换 Canvas.Top 和 Canvas.Left 就足够了,但怎么能做到呢?... 这个完成了。
    • 我应该如何将Transform 绑定到Canvas.Top
    • 为了完整起见,Transform 可以使用MultibindingConverter 绑定到Canvas.Top。查看我自己的分析器。
    【解决方案2】:

    我得到了一个通用的解决方案,它可以让我在 Canvases 上使用 Transforms 定位元素:

    多重绑定。

    我创建了两个使用 Transform 和坐标的 Multibinding 类(对于平移、缩放和剪切,它只需要一个坐标,但对于旋转,它需要 X 和 Y)并返回由 Transform 转换的坐标。所以我计算了两个Multibindings中的两个坐标。

    对于点,我有第三个多重绑定转换器,它返回转换后的点。

    它在 XAML 中需要一些代码,但在代码隐藏中没有特定代码,并且 Canvas 的缩放就像一个魅力。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2011-07-13
      • 2016-10-29
      • 1970-01-01
      • 1970-01-01
      • 2013-01-25
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多