【问题标题】:How do I override a property in a ControlTemplate?如何覆盖 ControlTemplate 中的属性?
【发布时间】:2013-01-08 14:40:36
【问题描述】:

我有以下 XAML:

<Window x:Class="WpfTest.MainWindow"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    Title="MainWindow" Height="227" Width="391">
    <Window.Resources>
        <ControlTemplate x:Key="PentagonButton" TargetType="{x:Type Button}">
            <Grid>
                <Path Data="M 0,-1 L -.95,-.3 L -.58,.8 L .58,.8 L .95,-.3 Z" Stroke="Black" Stretch="Uniform" Fill="Red" />
                <Viewbox>
                    <ContentPresenter Margin="20" />
                </Viewbox>
            </Grid>
        </ControlTemplate>
    </Window.Resources>
    <Grid>
        <Button Content="red" Margin="12,19,0,0" Template="{StaticResource PentagonButton}" HorizontalAlignment="Left" Width="166" Height="151" VerticalAlignment="Top" />        
        <Button Content="blue" Margin="178,19,0,0" Template="{StaticResource PentagonButton}" Height="151" VerticalAlignment="Top" HorizontalAlignment="Left" Width="173" />        
    </Grid>
</Window>

由于 Fill="Red",显然所有按钮都将具有红色填充/背景颜色。我想为几个按钮使用这个模板,但每个按钮都有不同的填充颜色,在设计时就知道了。设置背景颜色没有效果,所以我必须更改填充颜色,但我无法在实际按钮定义中再次定义 Path 属性。如何在 XAML 中访问和覆盖此属性?

【问题讨论】:

    标签: c# wpf


    【解决方案1】:

    不要直接使用模板。分配一个样式并使用它。

    即

     <Style x:Key="PentagonButton" TargetType="{x:type Button}">
     <Setter Property="Background" Value="Red"/>
        <Setter Property="Template">
        <Setter.Value>
          <ControlTemplate TargetType="{x:Type Button}">
                    <Grid>
                        <Path Data="M 0,-1 L -.95,-.3 L -.58,.8 L .58,.8 L .95,-.3 Z" Stroke="Black" Stretch="Uniform" Fill="{TemplateBinding Background}" />
                        <Viewbox>
                            <ContentPresenter Margin="20" />
                        </Viewbox>
                    </Grid>
                </ControlTemplate>
        </Setter.Value>
        </Setter>
        </Style>
    

    然后像这样使用它:

    <Grid>
            <Button Content="red" Margin="12,19,0,0" Style="{StaticResource PentagonButton}" HorizontalAlignment="Left" Width="166" Height="151" VerticalAlignment="Top" />        
            <Button Content="blue" Margin="178,19,0,0" Style="{StaticResource PentagonButton}" Height="151" VerticalAlignment="Top" HorizontalAlignment="Left" Width="173" Background="Blue" />        
        </Grid>
    

    【讨论】:

    • 您忘记设置红色按钮的背景属性。
    • 谢谢,为背景属性添加了设置器作为默认值
    • 谢谢,这行得通。 Florian Gl 的解决方案同样有效,而且代码更少 - 使用其中一个而不是另一个的充分理由是什么?直接使用模板而不是样式有缺点吗?
    • @Hackworth - 声明样式的优点是您可以在样式中提供 default 值,因此消费者只需要在更改默认值时指定属性。 WPF template How to provide default value,见行&lt;Setter Property="Background" Value="Red" /&gt;。如果你不需要这个,那么直接使用模板就可以了。
    【解决方案2】:

    使用 TemplateBinding 在其控件的 xaml 中更改模板的值:

                    <ControlTemplate x:Key="PentagonButton" TargetType="{x:Type Button}">
                        <Grid>
                            <Path Data="M 0,-1 L -.95,-.3 L -.58,.8 L .58,.8 L .95,-.3 Z" Stroke="Black" Stretch="Uniform" Fill="{TemplateBinding Background}" />
                            <Viewbox>
                                <ContentPresenter Margin="20" />
                            </Viewbox>
                        </Grid>
                    </ControlTemplate>
    

    您的按钮:

                    <Button Background="Red" Content="red" Margin="12,19,0,0" Template="{StaticResource PentagonButton}" HorizontalAlignment="Left" Width="166" Height="151" VerticalAlignment="Top" />
                    <Button Background="Blue" Content="blue" Margin="178,19,0,0" Template="{StaticResource PentagonButton}" Height="151" VerticalAlignment="Top" HorizontalAlignment="Left" Width="173" />
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-11-06
      • 1970-01-01
      • 2015-01-08
      • 2013-12-16
      • 1970-01-01
      相关资源
      最近更新 更多