前台属性行为混乱

发布于 2024-11-26 14:36:12 字数 2098 浏览 1 评论 0原文

我有一个像这样的自定义控件:

    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>

如果我运行它,它会像这样:

在此处输入图像描述

所以我的困惑是 ControlTemplate 中的 TextBlock 如下前景的局部值。但是 OnApplyTemplate 方法中添加的 TextBlock 遵循样式中的值。

但我想要的是一个仅在不存在本地值时遵循样式的 TextBlock。

那么为什么两个 TextBlock 的行为不同,如何在不存在本地值的情况下获得仅遵循样式的 TextBlock?

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

I have a custom control like this:

    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();
    }
}

and its control template is like this:

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

then I use it in the main window:

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

if I run it, it'll be like this:

enter image description here

So my confusion is that the TextBlock in ControlTemplate follows the local value of Foreground. But the TextBlock added in the OnApplyTemplate method follows the value from the style.

But what I want is a TextBlock that only follows the style when no local value is present.

So why do the two TextBlocks behave differently and how can I get a TextBlock that only follows the style when no local value is present?

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

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

知足的幸福 2024-12-03 14:36:12

当您将本地值应用于 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>

When you apply local value for Foreground you are applying to the CustomControl, whereas in the style you are applying only to TextBlock that makes lot of difference. Get rid of Grid.Resources and move your style setter directly in ControlTemplate and it will work as expected.

<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>
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文