59
votes

i have a wpf window where i have a stackpanel with two viewports in it - each Viewport with a textblock in it.

<Grid>
    <StackPanel VerticalAlignment="Center" Orientation="Vertical" >
        <Viewbox Margin="100,0,100,0">
            <TextBlock x:Name="headerText" Text="Lorem ipsum dolor" Foreground="Black"/>
        </Viewbox>
        <Viewbox Margin="150,0,150,0">
            <TextBlock x:Name="subHeaderText" Text="Lorem ipsum dolor, Lorem ipsum dolor, lorem isum dolor, Lorem ipsum dolor, Lorem ipsum dolor, lorem isum dolor, " TextWrapping="Wrap" Foreground="Gray" />
        </Viewbox>
    </StackPanel>
</Grid>

What i would like to achieve is that the top textblock is the heading with a bigger text. The second textblock is the sub heading with a smaller text. No matter how much text there is for either the heading or the subheading the font should dynamic become smaller/bigger. My problem is that i would like the subheading to be fixed width. This means that, the font should be a percentage (70%) of the heading and wrap to multiple lines, depending on how much text i have. I enclosed the code I have thus far... im missing something with that subheading, cant figure out what. Cheers

Edit Basically what i want achieve is that the sub header wraps the text so it can expand it downwards with the font being a 70% of the heading - no matter how big that font is.

5
What is the rule / equation for dynamic sizing. OK the sub is 70% but how to size the first? If you want a fixed width for the second TextBlock then set the Width.paparazzo
This is for use in an environment where i do not know the screen size/resolution. So the width is set using margins, thus allowing me to behave the same on all screens. The size of the heading is determined by the viewport, this means that the textblock always is shown in maximum size. - again depending on the screen resolution.Brian Hvarregaard

5 Answers

93
votes

Nesting a stackpanel will cause the textbox to wrap properly:

<Viewbox Margin="120,0,120,0">
    <StackPanel Orientation="Vertical" Width="400">
        <TextBlock x:Name="subHeaderText" 
                   FontSize="20" 
                   TextWrapping="Wrap" 
                   Foreground="Black"
                   Text="Lorem ipsum dolor, lorem isum dolor,Lorem ipsum dolor sit amet, lorem ipsum dolor sit amet " />
    </StackPanel>
</Viewbox>
47
votes

Use the property TextWrapping of the TextBlock element:

<TextBlock Text="StackOverflow Forum"
           Width="100"
           TextWrapping="WrapWithOverflow"/>
36
votes

Use Linebreak:

<TextBlock>
        <Run Text="Line1"/>
        <LineBreak/>
        <Run Text="Line2" FontStyle="Italic" FontSize="9"/>
        <LineBreak/>
        <Run Text="Line3"/>
    </TextBlock>

Refer this: https://social.msdn.microsoft.com/Forums/vstudio/en-US/51a3ffe4-ec82-404a-9a99-6672f2a6842b/how-to-give-multiline-in-textblock?forum=wpf

Thanks,

RDV

4
votes

This gets part way there. There is no ActualFontSize property but there is an ActualHeight and that would relate to the FontSize. Right now this only sizes for the original render. I could not figure out how to register the Converter as resize event. Actually maybe need to register the FontSize as a resize event. Please don't mark me down for an incomplete answer. I could not put code sample in a comment.

    <Window.Resources>
        <local:WidthConverter x:Key="widthConverter"/>
    </Window.Resources>
    <Grid>
        <Grid>
            <StackPanel VerticalAlignment="Center" Orientation="Vertical" >
                <Viewbox Margin="100,0,100,0">
                    <TextBlock x:Name="headerText" Text="Lorem ipsum dolor" Foreground="Black"/>
                </Viewbox>
                <TextBlock Margin="150,0,150,0" FontSize="{Binding ElementName=headerText, Path=ActualHeight, Converter={StaticResource widthConverter}}" x:Name="subHeaderText" Text="Lorem ipsum dolor, Lorem ipsum dolor, lorem isum dolor, Lorem ipsum dolor, Lorem ipsum dolor, lorem isum dolor, " TextWrapping="Wrap" Foreground="Gray" />
            </StackPanel>
        </Grid>
    </Grid>        

Converter

    [ValueConversion(typeof(double), typeof(double))]
    public class WidthConverter : IValueConverter
    {
        public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
        {
            double width = (double)value*.7;
            return width; // columnsCount;
        }

        public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
        {
            throw new NotImplementedException();
        }
    } 
2
votes

If you just want to have your header font a little bit bigger then the rest, you can use ScaleTransform. so you do not depend on the real fontsize.

 <TextBlock x:Name="headerText" Text="Lorem ipsum dolor">
                <TextBlock.LayoutTransform>
                    <ScaleTransform ScaleX="1.1" ScaleY="1.1" />
                </TextBlock.LayoutTransform>
  </TextBlock>