10

Is there a simple way to just get TextTrimming to work with a ContentPresenter?

I have implict styles for TextBlock and AccessText that have TextTrimming set to CharacterEllipsis, but it's not picked up by the ContentPresenter. I can change the ContentPresenter to an AccessText or TextBlock and set it there, but then the template only handles text content.

Any suggestions?

Thanks!

Ben
  • 54,723
  • 49
  • 178
  • 224
dex3703
  • 2,077
  • 4
  • 28
  • 45

2 Answers2

13

Implicit Styles for elements that derive from UIElement, but not Control, are not applied if the element is defined in a control's Template unless the implict Style is defined in the application Resources. The same holds true for TextBlocks used by ContentPresenter.

For example, in the following XAML the TextBlock that is ultimately used to present the button's content will not get the implicit Style:

<Window.Resources>
    <Style TargetType="TextBlock">
        <Setter Property="Foreground" Value="Red" />
    </Style>
</Window.Resources>
<StackPanel>
    <Button Content="Will not be red" />
    <TextBlock Text="Will be red" />
</StackPanel>

If you take that exact same Style and move it to the application's Resources, then both will be red:

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

So you can either move your implicit Style to application resources, which is generally not a good idea. Or you can customize the display for the specific scenario you have. This can include adding an implicit DataTemplate, or customizing a control's Template.

If you can provide more information, then it would be easier to know which is the best approach.

CodeNaked
  • 40,753
  • 6
  • 122
  • 148
  • 3
    @H.B. - I painted the town red! – CodeNaked Apr 28 '11 at 00:33
  • 1
    Thanks for this explanation! Another solution posted elsewhere defines a style in the ContentPresenter.Resources, inside the ControlTemplate. I tried this approach and it works. In our case moving the implicit style to Application.Resources would work as all textblocks are supposed to trim. Is adding an implicit datatemplate similar to what I"ve done above? How do you define a datatemplate so that you can support arbitrary content? – dex3703 Apr 28 '11 at 02:42
  • @dex3703 - You can't have a "global" implicit DataTemplate. You'd have to target the specific types you are displaying, i.e. String or any custom classes you may have. The implicit DataTemple would be useful for cases where you don't want to redefine the ControlTemplate (just to add TextTrimming). But again, the implicit DataTemplate wouldn't apply to arbitrary content. – CodeNaked Apr 28 '11 at 11:40
  • Is there some reason why adding texttrimming or textwrapping is so hard? – dex3703 Apr 28 '11 at 15:56
  • @dex3703 - Well, in general you wouldn't want to apply text trimming/wrapping to all TextBlocks. For example, it doesn't really make sense in buttons (in most cases). That's why the implicit Styles don't get applied, unless they are in the App resources (or the template apparently). But there are too many properties to expose them all by the parent elements. But to answer your question, probably, but I'm not exactly sure why :-) – CodeNaked May 03 '11 at 20:07
  • Thanks. It happens to be a design requirement for our product that everything trim, so a simple App.Resources style with texttrimming set would work great. However now we do apply merged dictionaries at the app.xaml with styles that include this, and they aren't applied. Do we need to have a style that calls out texttrimming in the app resources directly? – dex3703 May 04 '11 at 17:33
  • @dex3703 - A quick test shows that you can merge in dictionaries to the Application.Resources and it still works. You must be merging differently than my simple test though. – CodeNaked May 04 '11 at 17:39
9

Thanks to this Gist by James Nugent: "WPF style which puts character ellipsis on button contents without replacing the ContentPresenter with a TextBlock and thus losing the ability to support access keys."

This worked for me:

<ContentPresenter.Resources>
    <Style TargetType="TextBlock">
        <Setter Property="TextTrimming" Value="CharacterEllipsis"></Setter>    
    </Style>
</ContentPresenter.Resources>
Ben
  • 54,723
  • 49
  • 178
  • 224