【问题标题】:How to centre an item over a point in a Canvas?如何将项目居中在画布中的一个点上?
【发布时间】:2012-12-11 07:54:54
【问题描述】:

我正在使用一个 ListBox,它的 DataTemplate 包含一个 Canvas。然后我绑定包含该 Canvas 的网格的左侧/顶部以将其移动到某个点。

然后我想让子 Grid 以我指定的 X、Y 坐标为中心,其中子 Grid 的大小根据其内容而变化。我计划通过使用 TranslateTransform 将 Grid 移动一半宽度来实现这一点。

我看不到如何设置 TranslateTransform,但是因为 ElementName 绑定在 DataTemplate 中不起作用。有什么想法可以实现吗?

<ItemsControl ItemsSource="{TemplateBinding SomeCollection}">
    <ItemsControl.ItemsPanel>
        <ItemsPanelTemplate>
            <Grid HorizontalAlignment="Stretch" VerticalAlignment="Stretch" />
        </ItemsPanelTemplate>
    </ItemsControl.ItemsPanel>
    <ItemsControl.ItemTemplate>
        <DataTemplate>
            <Canvas>
                <Grid x:Name="Container" 
                        Canvas.Left="{Binding X}" 
                        Canvas.Top="{Binding Y}"
                        Background="#88000000">
                    <Grid.RenderTransform>
                    <TranslateTransform X="{Binding ActualWidth, ElementName=Container, Converter={StaticResource NegativeHalfConverter}}"
                                        Y="{Binding ActualHeight, ElementName=Container, Converter={StaticResource NegativeHalfConverter}}" />
                </Grid.RenderTransform>
                <TextBlock Text="{Binding SomeValue}" FontSize="36" Foreground="White" />
            </Grid>
        </Canvas>
    </DataTemplate>
</ItemsControl.ItemTemplate>

`

【问题讨论】:

    标签: xaml canvas listbox windows-runtime


    【解决方案1】:

    我认为 ElementName 绑定应该在 DataTemplate 的名称范围内工作,但我看到有人抱怨绑定到 ActualWidth/Height 属性时绑定没有正确更新。也许您可以不进行复杂的设置,而只需实现一个附加行为,该行为接受一个 Point 参数并在关联对象(您的网格)的参数或大小发生变化时更新 Canvas.Left/Top 属性。

    【讨论】:

    • 等等,实现一个附加的行为来更新 Canvas Left/Top 属性,同时保持原来的 x,y 是“不复杂的设置”?本来以为将其翻译一半的宽度/高度要简单得多!
    • 好吧,在您的解决方案中,您必须创建一个新控件、新依赖项属性并在 XAML 中进行翻译。开发可重用的行为/附加属性将是一项类似的工作,您只需在容器上设置像 CanvasEx.Center={Binding Center} 这样的属性,将计算和事件处理的复杂性分解/隐藏到您的行为以后也可以在其他地方使用。复杂的部分是没有内置的 Behavior 类,但是 CodePlex 上有开源的,或者你可以自己做一个基于附加属性的类。
    【解决方案2】:

    看起来问题不在于绑定本身,而在于一个意味着 ActualWidth/ActualHeight 属性不可绑定的特性。谢谢菲利普。

    为了解决这个问题,我创建了一个派生的 Grid,其中包含几个新的依赖属性,我在 SizeChanged 事件中更新这些属性以获得 ActualWidth/Height。然后我使用上面的 DataTemplate,绑定到这些新的 DP,以将我的 Grid 转换和居中在一个点上。似乎是一种享受。

    【讨论】:

      【解决方案3】:

      要将对象移动其大小的一半,您可以使用 2 次旋转或缩放:第一次超过 0.25,0.25 相对点,第二次超过输入点 0.5,0.5。如果你使用旋转,那么天使是 180 度和 -180 度。如果您使用比例,则比例因子为 -1,-1 和 -1,-1。 不要忘记 RenderTransformOrigin 属性。要应用两个变换,您可以将它们应用到两个嵌套元素。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2018-03-04
        • 1970-01-01
        • 1970-01-01
        • 2017-10-17
        • 2016-11-27
        相关资源
        最近更新 更多