4

Ive been trying to figure out how to obtain information from richtextbox if text is bolded, underlined or italic. So if I read a line from richtextbox, I need to know if some of the words is bolded etc? I dont want to save the contents to .rtf but to another, so that's why I need to know which words are formatted to something so I can add tags before the word to save contents like to .txt file.

Yes, it works if you make it like this

private void Button_Click(object sender, RoutedEventArgs e)
{
    foreach (Paragraph p in myRichTextBox.Document.Blocks)
    {
        foreach (var inline in p.Inlines)
        {
            if (inline.FontWeight == FontWeights.Bold)
            {
                // obtain text from p
            }               
        }
    }
}

How I can obtain text which is bolded?

Jon Koivula
  • 899
  • 1
  • 11
  • 24
  • Interesting. I don't know the answer myself but just give it a look if till now you haven't. http://msdn.microsoft.com/en-us/library/ee681613(v=vs.95).aspx – A.K. Jan 23 '14 at 11:18

1 Answers1

2

RTB in WPF contains FlowDocument. Hence, you can parse document's tree, and detect, which inline contains particular text. The basic concept:

<Grid>
    <Grid.RowDefinitions>
        <RowDefinition/>
        <RowDefinition Height="Auto"/>
    </Grid.RowDefinitions>

    <RichTextBox x:Name="myRichTextBox">
        <RichTextBox.Document>
            <FlowDocument>
                <Paragraph>
                    <Bold>Lorem ipsum dolor sit amet, consectetur adipiscing elit.</Bold>
                </Paragraph>
                <Paragraph>
                    <Italic>Lorem ipsum dolor sit amet, consectetur adipiscing elit.</Italic>
                </Paragraph>
                <Paragraph>
                    <Underline>Lorem ipsum dolor sit amet, consectetur adipiscing elit.</Underline>
                </Paragraph>
            </FlowDocument>
        </RichTextBox.Document>
    </RichTextBox>

    <Button Grid.Row="1" Content="Parse" Click="Button_Click"/>
</Grid>

Code-behind:

    private void Button_Click(object sender, RoutedEventArgs e)
    {
        foreach (Paragraph p in myRichTextBox.Document.Blocks)
        {
            foreach (var inline in p.Inlines)
            {
                if (inline is Bold)
                {
                    // ...
                }

                if (inline is Italic)
                {
                    // ...
                }

                if (inline is Underline)
                {
                    // ...
                }
            }
        }
    }

Note, that inlines can be nested:

                    <Underline>
                        Lorem ipsum dolor sit amet, consectetur adipiscing elit.
                        <Bold>
                            Lorem ipsum dolor sit amet, consectetur adipiscing elit.
                            <Italic>
                                Lorem ipsum dolor sit amet, consectetur adipiscing elit.
                            </Italic>
                        </Bold>
                    </Underline>

You should take this into consideration, when parsing content.

Dennis
  • 37,026
  • 10
  • 82
  • 150
  • The problem is im reading richtextbox contents like this way: range = new TextRange(richTextBox.Document.ContentStart, richTextBox.Document.ContentEnd); My contents is not in XAML code. Although I still tried your solution but none of if statements went true. – Jon Koivula Jan 23 '14 at 11:39
  • Could you tell me how do you get the text from P for which the inline matches? From inside if statements? – Jon Koivula Jan 23 '14 at 11:43
  • @JonKoivula: the way how do you fill RTB.Document doesn't matter. This is still FlowDocument. If you'll throw away `range = new TextRange(...` and directly parse document, you'll be able to find desired inlines. Note, that my code is just a sample and hard-coded to the sample content tree. In general, you'll need a more flexible parsing method. – Dennis Jan 23 '14 at 11:52
  • Can you give me example how I still get text from it? – Jon Koivula Jan 23 '14 at 11:57
  • @JonKoivula: get text from `FlowDocument` or `TextRange`? – Dennis Jan 23 '14 at 12:07
  • I can get text from range.Text but it takes the whole Content. Im sorry for probably asking dumb questions, but Ive been working with WPF for two days – Jon Koivula Jan 23 '14 at 12:17
  • Your `TextRange` matches the whole document. You don't need `TextRange` at all. Work with `richTextBox.Document` directly instead. – Dennis Jan 23 '14 at 12:32
  • System.Windows.Document.Run contains text property. Cant get to it from inline. If I could, I can call next inline with text and its formats. – Jon Koivula Jan 23 '14 at 12:43
  • Well im gonna make your answer correct because it answers to my question but not really to my whole problem. – Jon Koivula Jan 23 '14 at 12:57