前景财产行为混乱

时间:2011-07-26 19:34:07

标签: .net wpf xaml custom-controls controltemplate

我有这样的自定义控件:

    public class CustomControl1 : Control
{
    private StackPanel panel;

    static CustomControl1()
    {
        DefaultStyleKeyProperty.OverrideMetadata(typeof(CustomControl1), new FrameworkPropertyMetadata(typeof(CustomControl1)));
    }

    public override void OnApplyTemplate()
    {
        panel = (StackPanel)GetTemplateChild("root");
        panel.Children.Add(new TextBlock { Text = "TextBlock added in the OnApplyTemplate method" });

        base.OnApplyTemplate();
    }
}

及其控件模板如下:

<Style TargetType="{x:Type local:CustomControl1}">
    <Setter Property="Template">
        <Setter.Value>
            <ControlTemplate TargetType="{x:Type local:CustomControl1}">
                <StackPanel Name="root">
                    <TextBlock>TextBlock added in ControlTemplate</TextBlock>
                </StackPanel>
            </ControlTemplate>
        </Setter.Value>
    </Setter>
</Style>

然后我在主窗口中使用它:

<Window x:Class="WpfApplication1.MainWindow"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    Title="MainWindow" Height="350" Width="525"
    xmlns:app1="clr-namespace:WpfApplication1">
<Grid>
    <Grid.Resources>
        <Style TargetType="TextBlock">
            <Setter Property="Foreground" Value="Green"></Setter>
        </Style>
    </Grid.Resources>

    <app1:CustomControl1 Foreground="Red">

    </app1:CustomControl1>
</Grid>

如果我运行它,它将是这样的:

enter image description here

所以我的困惑是ControlTemplate中的TextBlock遵循Foreground的本地值。但OnApplyTemplate方法中添加的TextBlock遵循样式中的值。

但我想要的是一个TextBlock,只有当没有本地值时才会遵循样式。

那么为什么两个TextBlocks的行为不同呢?如果没有本地值,我怎样才能得到一个只跟随样式的TextBlock?

  

注意:如何在自定义控件内部创建TextBlocks   受网格资源中的隐式样式影响(其中   包含自定义控件。)

1 个答案:

答案 0 :(得分:2)

当您应用Foreground的本地值时,您正在应用CustomControl,而在您应用于TextBlock的样式中,这会产生很大的不同。摆脱Grid.Resources并直接在ControlTemplate中移动您的样式设置器,它将按预期工作。

<Style TargetType="{x:Type local:CustomControl1}">
    <Setter Property="Foreground" Value="Green"></Setter>
    <Setter Property="Template">
        <Setter.Value>
            <ControlTemplate TargetType="{x:Type local:CustomControl1}">
                <StackPanel Name="root">
                    <TextBlock>TextBlock added in ControlTemplate</TextBlock>
                </StackPanel>
            </ControlTemplate>
        </Setter.Value>
    </Setter>
</Style>