2

I'm currently trying to make it so that when I take a string, it fills up the first textblock until it overflows and then it should start in textblock 2. Currently, I have it to where the string is cut into two pieces at the last end of the last word before it hits what I guess to be the max characters that can fit into textblock one, and the second half is in 2, but the problem I'm encountering is that it's never really possible to figure out where to cut off text, since when it wraps, the spaces left over take up different sizes. So I'm left with textblock 1 having some cut off text at the end, making it look like some words are missing between the two. Is there any way to programmatically find the overflow on a textblock?

ps- the Textblocks are created at runtime in the C# instead of the wpf markup.

This is what I do. I take myDescription and try to fit it into myDesc[0] and then [2] based on the sizes I approximate. The problem is that if I guess the size threshold to be too big, it leaves myDesc[0] with a ... or cut off word, and if I approximate it to be too little, it has huge awkward gaps. There's no number that I cut off that doesn't have either.

TextBlock[] myDesc = new TextBlock[2];
string myDescription = infoLoader.games[gameID].description[currentLanguage];
        string[] myWords = myDescription.Split(' ');

        string firstPart = "";
        string secondPart = "";


        int currentWord = 0;


        // New and improved way
        int currentLine = 0;
        int charsInLine = 0;
        while (currentWord < myWords.Length)
        {
            // Determine the size of the word based on the number of characters and size of certain characters in it.
            int myWLength = myWords[currentWord].Length;
            int iCount = 0;
            for (int i = 0; i < myWords[currentWord].Length; i++)
            {
                if (myWords[currentWord][i] == 'm' || myWords[currentWord][i] == 'M')
                {
                    Console.Write("M or m. ");
                    myWLength++;
                }
                else if (myWords[currentWord][i] == 'i' || myWords[currentWord][i] == 'l' || myWords[currentWord][i] == 'I' || myWords[currentWord][i] == 'j' || myWords[currentWord][i] == 'í' || myWords[currentWord][i] == 't')
                {
                    iCount++;
                }
            }
            iCount = (iCount / 2);
            myWLength -= iCount;
            if (myWords[currentWord] == "SKIP")
            {
                firstPart += "\n";
                currentLine++;
                currentWord++;
            }
            else if (currentLine < 4)
            {
                // firstPart.
                if (charsInLine + myWLength < 20)
                {
                    // Add It.
                    firstPart += myWords[currentWord];
                    firstPart += " ";
                    charsInLine += myWLength;
                    charsInLine += 1;
                    currentWord++;

                }
                else
                {
                    // New Line.
                    //firstPart += " " + currentLine + " ";
                    firstPart += "\n";
                    charsInLine = 0;
                    currentLine++;
                }
            } else if (currentLine < 6) 
            {
                if (charsInLine + myWLength < 21)
                {
                    // Add It.
                    firstPart += myWords[currentWord];
                    firstPart += " ";
                    charsInLine += myWLength;
                    charsInLine += 1;
                    currentWord++;

                }
                else
                {
                    // New Line.
                    //firstPart += "\n";
                    charsInLine = 0;
                    currentLine++;
                }
            }
            else
            {
                // secondPart.
                secondPart += myWords[currentWord];
                secondPart += " ";
                currentWord++;
            }
        }

myDesc[0] = new TextBlock();
        myDesc[0].Text = firstPart;
        myDesc[0].TextWrapping = TextWrapping.Wrap;
        myDesc[0].TextTrimming = TextTrimming.CharacterEllipsis;
        myDesc[0].Background = descBGBrush;
        myDesc[0].FontFamily = new FontFamily("Arial");
        myDesc[0].FontSize = 12.0;
        myDesc[0].Width = 118;
        myDesc[0].Height = 83;
        Canvas.SetLeft(myDesc[0], 132);
        Canvas.SetTop(myDesc[0], 31);

        myDesc[1] = new TextBlock();
        myDesc[1].Text = secondPart;
        myDesc[1].TextWrapping = TextWrapping.Wrap;
        myDesc[1].Background = descBGBrush;
        myDesc[1].FontSize = 12.0;
        myDesc[1].FontFamily = new FontFamily("Arial");
        myDesc[1].Width = 236;
        myDesc[1].Height = 43;
        Canvas.SetLeft(myDesc[1], 16);
        Canvas.SetTop(myDesc[1], 115);
3
  • What do you mean by Overflow. You have the textblock with constant width? Commented Sep 4, 2010 at 9:10
  • do you just want your text Justified? Commented Sep 4, 2010 at 10:11
  • What I am trying to do is that when the text goes outside the bounds of a textblock (with wrapping), instead of cutting off, the remaining text is then put to a second textblock Commented Sep 16, 2010 at 5:20

2 Answers 2

8

Take a look at the TextWrapping property associated with the TextBlock to perhaps make your code simplier.

<StackPanel>
  <TextBlock Text="One line of text"/>
  <TextBlock Width="50" TextWrapping="WrapWithOverflow" Text="One line of text"/>
  <TextBlock Width="50" TextWrapping="Wrap" Text="One line of text"/>
</StackPanel>
Sign up to request clarification or add additional context in comments.

Comments

1

A way is to create create a custom-control where you do the rendering over DrawingContext. With this, you can exactly calculate the size that the text will use and therefore calculate the cut-position.

With such a control, you can define an overflow-property that returns for each control the text that is not shown and set it as source of a sibling-control.

Sure, this is not a simple job, but it's a possible way. You can also derive from TextBlock and then calculate the text in the default-processing logic and add a DP to provide the overflow text.

The following links may be usefull to do the above solution:

FormattedText

FormattedText.Height

2 Comments

"With such a control, you can define an overflow-property that returns for each control the text that is not shown and set it as source of a sibling-control."
Sorry, meant to be one comment, but I'm not sure exactly how to go about doing that. I'll explain what I'm doing better above

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.