1

I'm in pretty new to C# WPF and recently meet a very weird problem.

I'm managing style sheet xaml files as following pictures and code.

File Structure

[ App.xaml ]

<Application.Resources>
    <ResourceDictionary>
        <ResourceDictionary.MergedDictionaries>
            <ResourceDictionary Source="Styles/StyleText.xaml"/>
            <ResourceDictionary Source="Styles/StyleButton.xaml"/>
        </ResourceDictionary.MergedDictionaries>
    </ResourceDictionary>
</Application.Resources>

[ StyleText.xaml ]

<Style TargetType="TextBlock">
    <Setter Property="Foreground" Value="Red"/>
</Style>

[ StyleButton.xaml]

<Style TargetType="{x:Type Button}">
    <Setter Property="Template">
        <Setter.Value>
            <ControlTemplate TargetType="Button">
                <TextBlock x:Name="TblockTest" Background="Gray" Foreground="Blue">
                    <TextBlock.Resources>
                        <Style TargetType="TextBlock">
                            <Setter Property="Foreground" Value="Green"/>
                        </Style>
                    </TextBlock.Resources>
                    <ContentPresenter x:Name="CpCustomButton" ContentSource="Content"/>
                </TextBlock>
                <ControlTemplate.Triggers>
                    <Trigger Property="IsMouseOver" Value="False">
                        <Setter TargetName="CpCustomButton" Property="TextBlock.Foreground" Value="Black"/>
                    </Trigger>
                </ControlTemplate.Triggers>
            </ControlTemplate>
        </Setter.Value>
    </Setter>
</Style>

These are test codes to reproduce the problem.

What I want to do is ignore the style of StyleText.xaml inside StyleButton.xaml without addressing key to the textblock style in StyleText.xaml

As you know, textblock style without key will serve the global style, and so I don't have to insert annoying 'style={~~}' code per textblock.

But now, I can't avoid that it infects the style of textblock inside of control template for other control like button.

As you can see in the StyleButton.xaml, I tried several things that I can think and googled so much times, but nothing solves this problem clearly.

The content of a button always shows in Red which is the color addressed by StyleText.xaml.

What should I do to solve the problem?

I also attach my test solution noted above.

https://www.dropbox.com/s/no0j60px2qnl51y/WeirdProblem.zip

Thanks to read.

J.-H. Bak
  • 15
  • 4
  • 1
    A button control has code in it will add a textblock into the contentpresenter when content is a string. If you run snoop and take a look. You have a button with a textblock in it, in that is a contentpresenter. In that is a textblock. Your controltemplate is faulted. It should probably be just a textblock with text templatebinding to content. – Andy Dec 18 '19 at 13:33
  • Actually this is an example to reproduce the problem. What I tried was a more complicated Tab Control style. But your words give me inspiration on the problem. I'll try much more experiments based on your saying. Thanks a lot!! – J.-H. Bak Dec 18 '19 at 14:26
  • 1
    Labels also can have an auuto-generated textblock in them. But your "real" problem could be somewhat different and templating and or scope related. – Andy Dec 18 '19 at 14:57
  • Hey, I just solved the "real" problem based on your advice :D. Actually Michal's way also works, but your advice addressed exactly what I didn't understand. I really appreciate to you! – J.-H. Bak Dec 18 '19 at 15:06

1 Answers1

1

I downloaded the solution and here's a fix: move the TextBlock Foreground style from the TextBlock.Resources to ContentPresenter.Resources like this

<Style TargetType="{x:Type Button}">
    <Setter Property="Template">
         <Setter.Value>
              <ControlTemplate TargetType="Button">
                  <TextBlock
                      x:Name="TblockTest"
                      Background="Gray"
                      Foreground="Blue">
                      <ContentPresenter x:Name="CpCustomButton" ContentSource="Content">
                          <ContentPresenter.Resources>
                              <Style TargetType="TextBlock">
                                  <Setter Property="Foreground" Value="Green" />
                              </Style>
                          </ContentPresenter.Resources>
                      </ContentPresenter>
                  </TextBlock>
                  <ControlTemplate.Triggers>
                      <Trigger Property="IsMouseOver" Value="False">
                          <Setter TargetName="CpCustomButton" Property="TextBlock.Foreground" Value="Black" />
                      </Trigger>
                  </ControlTemplate.Triggers>
              </ControlTemplate>
         </Setter.Value>
    </Setter>
</Style>

I'm not sure why it didn't use the style from the TextBlock.Resources when that is a parent to the ContentPresenter.

Hope that helps. Michal

Michal Diviš
  • 2,008
  • 12
  • 19