WPF:为啥我不应该在 ControlTemplate 中使用 TemplateBinding Margin - Margin 是不是仅适用于元素的容器?

Posted

技术标签:

【中文标题】WPF:为啥我不应该在 ControlTemplate 中使用 TemplateBinding Margin - Margin 是不是仅适用于元素的容器?【英文标题】:WPF: Why shouldn't I use TemplateBinding Margin in ControlTemplate - is Margin meant only for element's containers?WPF:为什么我不应该在 ControlTemplate 中使用 TemplateBinding Margin - Margin 是否仅适用于元素的容器? 【发布时间】:2011-01-01 16:30:55 【问题描述】:

我已经为 Button 创建了自己的 ControlTemplate,如下所示:

<Style x:Key="LightButtonStyle" TargetType="x:Type ButtonBase">
    <Setter Property="Template">
        <Setter.Value>
            <ControlTemplate TargetType="x:Type ButtonBase">
                <Border
                    x:Name="WrappingBorder"
                    Margin="TemplateBinding Margin"
                    ...
                    >
                    <ContentPresenter 
                        Content="TemplateBinding Content" 
                        ...
                        >
                    </ContentPresenter>
                </Border>
            </ControlTemplate>
        </Setter.Value>
    </Setter>
</Style>

现在,我注意到当我为按钮设置边距时,例如:

<Button 
    Style="StaticResource LightButtonStyle"
    Margin="20"
    >
    Hello world!
</Button>

按钮实际上有两倍的 Margin - 40。我假设控件实际上不应该使用 Margin,并且 Margin 属性在排列阶段只能由按钮的祖先读取。然后我查看了 WPF 默认样式,发现没有一个使用 Margin。

这是正确的结论吗(Margin 只能由容器正确排列)?换句话说,每次我在我的风格中使用 TemplateBinding Margin 时,我会得到双倍边距吗? 是否有一些我的控件不应该使用的类似属性列表(因为它们仅适用于“周围世界”)?

你能把我指向解释这一点的 MSDN 页面吗?谢谢!

编辑:

我想我应该在http://msdn.microsoft.com/en-us/library/ms745058.aspx 和http://msdn.microsoft.com/en-us/library/ms751709.aspx 中找到答案,但我认为他们没有明确提到从不使用 Margin 属性的控件,它是 总是评估它并使用它来影响布局的祖先或 wpf 系统......

【问题讨论】:

【参考方案1】:

边距由布局系统自动应用,在控件模板内您应该使用 Padding。

<Border x:Name="WrappingBorder" Margin="TemplateBinding Padding" ... />

【讨论】:

Aviad 首先回复(并在稍后的评论中暗示了应用边距的阶段),所以我接受了他的回答 - 但也非常感谢!【参考方案2】:

您的结论是正确的,如果您查看框架提供的默认模板,您会发现模板内的Margin 绑定到控件的Padding 属性。

【讨论】:

谢谢,我注意到了……你知道一些 msdn 页面或博客文章可以解释 Margin(可能还有其他特定于布局的属性)在布局中的作用吗?我试图用谷歌搜索它,但没有找到真正的答案。 我相信谷歌可以帮助你,但我会说(或者更确切地说,写)一件事。容器在布局过程的排列过程中使用边距,容器会将子元素放置在从其水平和垂直对齐及其边距派生的位置。 谢谢,这正是我想要的——除了 Margin,我也不应该在模板中使用 s Horizo​​ntalAlignment 和 VerticalAlignment。

以上是关于WPF:为啥我不应该在 ControlTemplate 中使用 TemplateBinding Margin - Margin 是不是仅适用于元素的容器?的主要内容,如果未能解决你的问题,请参考以下文章

UISplitViewController:为啥我不应该在导航或标签栏界面中显示它?

为啥我不应该在访问对象之前使用“if Assigned()”?

为啥我不应该让一个类可序列化?

为啥要避免 WPF MVVM 模式中的代码隐藏?

为啥我不应该在 Impala 中的“COMPUTE STATS”和“COMPUTE INCREMENTAL STATS”之间切换?

为啥我不应该在 IDP 上下文中使用 IdToken 作为不记名令牌?