.net - 前台属性行为困惑

标签 .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。

那么,为什么这两个 TextBlock 的行为不同,我如何才能得到一个仅在不存在局部值时才遵循样式的 TextBlock?

Note: How can I make the TextBlocks inside of the custom control not affected by an implicit style in the Resources of the Grid(which contains the custom control).

最佳答案

当您为 Foreground 应用本地值时,您将应用到 CustomControl,而在样式中,您仅应用到 TextBlock很多不同。摆脱 Grid.Resources 并直接在 ControlTemplate 中移动您的样式 setter ,它将按预期工作。

<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>

关于.net - 前台属性行为困惑,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/6835486/

相关文章:

c# - 如何反序列化有时是空数组有时是字符串值的 JSON 数据

c# - C#.net 中的 XML 数据库

用简单的术语为 wpf mvvm 编写的 c# 类

wpf - 用于在 MVVM 中进行配置的对话框窗口

wpf - 如何拖放Drop Datagrid单元格内容

c# - WPF 将 ObservableCollection 绑定(bind)到 UserControl 的意外行为

C# - 无需端口转发即可远程控制 PC(如 TeamViewer)

c# - 如何恢复/中断 BackgroundWorker 线程

c# - MultiDataTrigger 不适用于绑定(bind)路径条件

c# - 添加货币符号到 `TextBlock`