模板化wpf控件中的内容对齐和定位

时间:2012-04-09 17:27:14

标签: wpf templates location

我是VB.NET中的专业Windows应用程序开发人员和Windows窗体的C#,现在非常兴奋能够进入WPF开发阶段。这是我的第一个问题,我无法通过搜索来解决:

我编写了以下模板来彻底改变按钮的外观:

    <ControlTemplate TargetType="{x:Type Button}" x:Key="ImageButtonTemplate">
        <Grid>
            <Image Name="img" Source="/PSPlayer;component/Images/Buttons/ButtonNormal_normal.png"/>
            <ContentPresenter Stylus.IsTapFeedbackEnabled="False" Stylus.IsTouchFeedbackEnabled="False" Stylus.IsPressAndHoldEnabled="False" Stylus.IsFlicksEnabled="False" Width="98" Height="61"/>
        </Grid>

        <ControlTemplate.Triggers>
            <Trigger Property="IsMouseOver" Value="True">
                <Setter TargetName="img" Property="Source" Value="/PSPlayer;component/Images/Buttons/ButtonNormal_MouseOver.png"/>
            </Trigger>
            <Trigger Property="IsPressed" Value="True">
                <Setter TargetName="img" Property="Source" Value="/PSPlayer;component/Images/Buttons/ButtonNormal_MouseDown.png"/>
            </Trigger>
        </ControlTemplate.Triggers>
    </ControlTemplate>

这里有一个按钮定义:

        <Button Content="SomeText" Height="61" Margin="0,0,0,7" Name="button7" Width="98" Click="button7_Click" Template="{StaticResource ImageButtonTemplate}"/>

问题是,文本“SomeText”出现在按钮的左上角,我无法更改该位置。按钮的属性Horizo​​ntalContentAlignment和VerticalContentAlignment没有显示效果(我想知道为什么)。

此外,我想将文本定位到某个位置,有时像x = 70,当背景图像中有一个位于左侧的符号,直到x = 60。

我在按钮内嵌了一个可以定位的标签,但我认为必须有一个更清洁的解决方案。

希望我明白自己。 WPF规则顺便说一句 - 以及这个网站,我解决的大部分问题都来自这里(来自谷歌):)

提前致谢,

儒略

1 个答案:

答案 0 :(得分:7)

这里发生了一些事情。你的第一个问题是,您为您的ContentPresenter的绝对大小(一般在WPF,您避免绝对大小和控制绝对位置,但它是一个艰难的习惯,当你从WinForms的到来打破)。如果删除它,则可以通过设置ContentPresenter本身的VerticalAlignment和Horizo​​ntalAlignment来正确对齐。在按钮本身上设置VerticalAlignment和Horizo​​ntalAlignment的原因不起作用是因为您没有在模板中的任何位置使用这些属性。理想情况下,你会做这样的事情:

<ContentPresenter VerticalAlignment="{TemplateBinding VerticalAlignment}" Content="{TemplateBinding Content}" HorizontalAlignment="{TemplateBinding HorizontalAlignment}"/>

现在您可以在使用此模板的按钮上设置对齐方式。当然,如果你总是希望这个模板居中,你可以硬编码而不是使用TemplateBinding。

通常,在替换模板时要记住的事情是,在呈现控件时,WPF将忽略您未在模板中显式绑定的控件的任何属性。如果你不告诉它如何处理这些属性,它就不会猜测。一个罕见的例外是你的例子中的内容属性,你可以通过没有明确绑定来逃避,因为WPF会假设你打算把它放在ContentPresenter中!但是所有其他按钮属性都将被忽略。例如,如果您尝试更改模板化按钮的Background属性,它将被忽略,因为WPF不知道将该背景放在何处。它应该是整个控制吗?它应该是你的网格吗?只是你的ContentPresenter?你必须告诉它。