Click here to Skip to main content
15,892,005 members
Please Sign up or sign in to vote.
0.00/5 (No votes)
See more:
Hi guys and girls i'm back to give your brain a workout. Here's my problem: I've got a textbox in a button to display text. This works fine until the button resizes to fit to the panel it's in then the text wraps and gets cut off. So now i want to test the linecount and then add a trigger to make the font smaller. Can anyone show me how linecount works in xaml on a textbox or textblock? Or maybe if you know of a better way could you give me a shout?
Thanks in advance
Posted

You can wrap your TextBlock with a Viewbox, like the following:


XML
<Button>
    <Viewbox>
        <TextBlock Text="Text Text" />
    </Viewbox>
</Button>

Edited:


For setting the same fontsize to the whole of the TextBlocks, you can scale the fontsize of the whole of the TextBlocks, according to the TextBlock with the minimal scale.


To achieve the scale effect, the Viewbox wraps the element with a ContainerVisual and, performs a scale on it. You can add an event-handler to the SizeChanged event of the Viewbox. In this event-handler you can use the scale value of the ContainerVisual that wraps the TextBlock to change the fontsize of the other TextBlocks, like the following example:


XML
<Grid>
    <Grid.RowDefinitions>
        <RowDefinition />
        <RowDefinition />
    </Grid.RowDefinitions>
    <Button>
        <Viewbox Name="vb1" StretchDirection="DownOnly" SizeChanged="vb1_SizeChanged">
            <TextBlock Name="tb1" Text="Text Text" FontSize="72" />
        </Viewbox>
    </Button>
    <Button Grid.Row="1">
        <Viewbox Name="vb2" StretchDirection="DownOnly">
            <TextBlock Name="tb2" Text="Text2" FontSize="72" />
        </Viewbox>
    </Button>
</Grid>

C#
private void vb1_SizeChanged(object sender, SizeChangedEventArgs e)
{
    ContainerVisual cv = VisualTreeHelper.GetParent(tb1) as ContainerVisual;
    ScaleTransform st = cv != null ? cv.Transform as ScaleTransform : null;
    if (st != null)
    {
        tb2.FontSize = 72 * st.ScaleX;
    }           
}

In this example we have a Grid that has only 2 buttons and, the 1st TextBlock effects the 2nd. But, you can use the idea also for more complicated cases.

 
Share this answer
 
v3
Comments
Ace_Hardlight 25-Oct-11 3:20am    
tried that but then it changes the fontsize for every individual textbox in my list. Which ends up to be different for each textbox as the text wraps
Shmuel Zang 25-Oct-11 3:43am    
If you want it to change the fontsize only if the text is too big, you can set the 'StretchDirection' property of the Viewbox to 'DownOnly'.
Ace_Hardlight 25-Oct-11 4:10am    
What i mean is it makes my buttons' fonts uneven. If i have a button with text "blah blah blah blah blah" it's going to be smaller, and another button with only "blah" the first button will have a smaller font than the second. I don't want this difference between buttons. All the button's fonts must resize even if just one button's text is too big
Shmuel Zang 25-Oct-11 5:48am    
Ok, now it's more clear. See the edited solution.
If you have the actual width and height of the drawn text you could calculate line count and even adjust the font size to fit the text into an area.

Get text size by using this snippet :

C#
FormattedText formattedText = new FormattedText("This is a long long multi line text.",
                                                System.Globalization.CultureInfo.GetCultureInfo("en-us"),
                                                FlowDirection.LeftToRight,
                                                new Typeface("Tahoma"), FontSize = 16, Brushes.Black);
MessageBox.Show(string.Format("{0}, {1}", formattedText.Width, formattedText.Height));


Then divide this text's length to the width of the area ,in which it should be displayed (and round up the result) to obtain the line count.

Hope it helps.
 
Share this answer
 
[After clarification by OP, alternative answer]

It looks like you need to calculate actual metrics of the rendered text, taking into account all what's involved in final rendering: its font, system rendering settings, bounding element, presentation style (wrapped or not), etc. Just a note: this problem is very complex due to complexity of text rendering and application of effect like anti-aliasing, optional ClearType (http://en.wikipedia.org/wiki/ClearType[^]), font hinting (http://en.wikipedia.org/wiki/Hinting[^]), etc. For example, with System.Drawing, all method I ever heard of produce not 100% accurate results.

In WPF, this problem is solved using the class System.Windows.Media.FormattedText, see http://msdn.microsoft.com/en-us/library/system.windows.media.formattedtext%28v=VS.100%29.aspx[^].

—SA
 
Share this answer
 
No, no, line count does not depend on bounding box, rendered text sized and word wrapping. It counts "real" lines, those separated with line end string or characters, "\n", "\r" or "\r\n" (any of them, in fact).

(By the way, to write correct portable end-of-line, always use static property System.Environment.NewLine, http://msdn.microsoft.com/en-us/library/system.environment.newline.aspx[^].)

—SA
 
Share this answer
 
v2
Comments
Ace_Hardlight 25-Oct-11 3:02am    
Ok but this doesn't actually help me. Now i know not to use linecount but how am i going to determine if the textlenght is longer than a certain amount in xaml itself?
Sergey Alexandrovich Kryukov 25-Oct-11 10:34am    
You did not ask about it... I will answer, wait up.
--SA
Sergey Alexandrovich Kryukov 25-Oct-11 10:46am    
Please see my other solution.
--SA

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)



CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900