WPF button textwrap style

61,494

Solution 1

Your second version should work, and does for me, with the caveat that you need to change the TextBlock Text binding:

<!-- in Window.Resources -->
<Style x:Key="fie" TargetType="Button">
  <Setter Property="Template">
    <Setter.Value>
      <ControlTemplate TargetType="{x:Type Button}">
        <TextBlock Text="{TemplateBinding Content}" FontSize="20" TextWrapping="Wrap"/>
      </ControlTemplate>
    </Setter.Value>
  </Setter>
</Style>

<!-- then -->
<Button Style="{StaticResource fie}">verylongcaptiongoeshereandwraps/Button>

Note this completely replaces the button style (i.e. you will need to create your own button chrome if you want it).

Regarding your second question, all writeable dependency properties can be set using a Setter. The reason you were unable to set TextWrapping on a Button via a style is that Button does not have a TextWrapping dependency property (or indeed any TextWrapping property). There are no "magic words," just the names of dependency properties.

Solution 2

To expand Eric's answer with an example:-

<Button Name="btnName" Width="50" Height="40">
   <TextBlock Text="Some long text" TextWrapping="Wrap" TextAlignment="Center"/>
</Button>

Solution 3

I solved this problem by adding a TextBlock to the button, and using it to display the button text instead of the button's Content property. Be sure to set the TextBlock's height property to Auto, so that it grows in height to accommodate the number of lines of text as it wraps.

Solution 4

<Style TargetType="Button">
    <Setter Property="ContentTemplate">
        <Setter.Value>
            <DataTemplate>
                <TextBlock Text="{TemplateBinding Content}" TextWrapping="Wrap" />
            </DataTemplate>
        </Setter.Value>
    </Setter>
</Style>

Solution 5

Here's an example of Eric's answer in C# code-behind:

var MyButton = new Button();

MyButton.Content = new TextBlock() {
    FontSize        = 25,
    Text            = "Hello world, I'm a pretty long button!",
    TextAlignment   = TextAlignment.Center,
    TextWrapping    = TextWrapping.Wrap
};
Share:
61,494
mmr
Author by

mmr

Updated on July 09, 2022

Comments

  • mmr
    mmr almost 2 years

    How do I change the default textwrapping style of a button in WPF?

    The obvious solution of:

    <Style x:Key="MyButtonStyle" TargetType="{x:Type Button}">
        <Setter Property="TextWrapping" Value="Wrap"></Setter>
    </Style>
    

    doesn't work, because Textwrapping isn't a settable property here, apparently.

    If I try:

    <Style x:Key="MyButtonStyle" TargetType="{x:Type Button}">
        <Setter Property="Template">
            <Setter.Value>
                <ControlTemplate TargetType="{x:Type Button}">
                    <TextBlock Text="{Binding}" Foreground="White" FontSize="20" FontFamily="Global User Interface" TextWrapping="Wrap"/>
                </ControlTemplate>
            </Setter.Value>
        </Setter>
    </Style>
    

    I just get a worthless response from the compiler:

    Error   5   After a 'SetterBaseCollection' is in use (sealed), it cannot be modified.   
    

    Removing the ControlTemplate tag keeps the error.

    The following attempt yields a different error:

        <Setter Property="TextBlock">
            <TextBlock Text="{Binding}" Foreground="White" FontSize="20" FontFamily="Global User Interface" TextWrapping="Wrap"/>
        </Setter>
    
    Error   5   The type 'Setter' does not support direct content.  
    

    I see that I can set the textwrapping for each button individually, but that's pretty asinine. How can I do it as a style? What are the magic words?

    And for future reference, where can I find a list of these magic words, so I can just do this on my own? The MSDN entry is pretty useless when I try to find out about which properties can be set by the setter.

  • mmr
    mmr about 15 years
    No, there are magic words. In this case, the magic words were "TemplateBinding Content." Thanks for letting me know.
  • John B
    John B about 12 years
    This is definitely easier/cleaner than the accepted answer, but his way does work too.
  • Danny Beckett
    Danny Beckett over 9 years
    See the below answers for examples of the code needed.
  • imekon
    imekon about 6 years
    I didn't have a width and height on the button, instead I used MaxWidth on the text - limits the size and it wraps nicely!
  • fadden
    fadden about 4 years
    Change TextBlock to AccessText if you want to be able to specify access keys (Text="_Some long text").
  • Lynn Crumbling
    Lynn Crumbling over 2 years
    Thank you SO much for mentioning the height=Auto....
  • Jerry
    Jerry over 2 years
    This is the answer people should choose if they are looking to universally make all of their buttons wrap text without destroying the chrome.