-1

I have below WPF RichTextBox which is bound to an MVVM property in my view model. The property SampleText contains a string, let's say, e.g.:

Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.

I would like to make it visible in the RichTextBox in the following way:

enter image description here

As seen above, I would like to show all the paragraph using the same font (Segoe UI) but with some words highlighted in bold and the first phrase using a bigger font size.

Below my code:

<RichTextBox IsReadOnly="True"
             Focusable="False">
    <FlowDocument>
         <Paragraph>
               <Run Text="{Binding SampleText}" />
         </Paragraph>
    </FlowDocument>
</RichTextBox>

In case of bold, I have tried and inserted some <Bold> and </Bold> pair tags around some words and they are not displayed in the RichTextBox as bold, instead the <Bold> and </Bold> tags are not recognized and they are simply displayed as is in the RichTextBox.

In case of applying a bigger font size for first line, I don't have idea on how to do it, I don't know what is the correct tags pair to use.

How can I do this in WPF?

My SampleText property is dynamically changed programmatically from code, I mean, I assign it different formatted values (by formatted i mean, applying tags like and , etc.) depending on the scenario so it would be good an approach that would work simply by assigning the formatted value to that property and then it would be automatically processed and displayed correctly in the RichTextBox.

Willy
  • 9,848
  • 22
  • 141
  • 284
  • Does this answer your question? [Making specific Text Boldefaced in a TextBox](https://stackoverflow.com/questions/6403902/making-specific-text-boldefaced-in-a-textbox) – Rekshino Jan 26 '23 at 08:23
  • Not sure if it will suit whatever your real world purpose is. You could put a FixedPage in a fixedDocument in a DocumentViewer. Then add paragraphs with textblocks etc in them. fixedPage.Children.Add(uiElement); You could xamlreader.parse a string into your elements or build controls. Not trivial but not difficult code to write. – Andy Jan 26 '23 at 16:18
  • @willy is my answer what you're looking for or are you trying to do something else? – Emperor Eto Jan 26 '23 at 20:49
  • @PeterMoore I have not tested yet but it could be a solution. The only problem with that is that I need to create a string with weird rtf codes. – Willy Jan 26 '23 at 21:16
  • 1
    Ok good deal, please let us know if it works for you or not. It should be completely happy with whatever RTF string you give it, as long as it's valid. I've used this with Word docs exported to RTF and it works fine. Cheers. – Emperor Eto Jan 26 '23 at 21:20

1 Answers1

1

I'm gonna say at the outset I'm sure I got this by synthesizing one or more SO answers from a lifetime ago, but I have no idea whom to credit as this code is at least 7 years old.

As I think you realized by now you can't actually just bind an RTF string to the RichTextBox (which, you know, would be too easy...), so instead I subclass and use a custom DP. You should easily be able to adapt this to your needs though.

    public class BindableRichTextBox : RichTextBox
    {
        #region string RichText dependency property
        public static readonly DependencyProperty RichTextProperty = 
            DependencyProperty.Register(
                "RichText", 
                typeof(string), 
                typeof(BindableRichTextBox), 
                new PropertyMetadata(
                    (string)null,
                    (obj, args) =>
                    {
                        ((BindableRichTextBox)obj).OnRichTextChanged(args);
                    }));
        public string RichText
        {
            get
            {
                return (string)GetValue(RichTextProperty);
            }
            set
            {
                SetValue(RichTextProperty, value);
            }
        }
        private void OnRichTextChanged(DependencyPropertyChangedEventArgs args)
        {
            string rtf = args.NewValue as string;
            if (string.IsNullOrEmpty(rtf))
            {
                this.Document = null;
                return;
            }
            this.Document = GetFlowDocumentFromRTF(rtf);
        }
        #endregion

        private FlowDocument GetFlowDocumentFromRTF(string text)
        {
            FlowDocument document = new FlowDocument();

            using (var ms = new MemoryStream(Encoding.UTF8.GetBytes(text)))
            {                    
                TextRange tr = new TextRange(document.ContentStart, document.ContentEnd);
                tr.Load(ms, DataFormats.Rtf);
            }
            return document;
        }
    }

To use this, you would then just say:

<local:BindableRichTextBox IsReadOnly="True"
                           Focusable="False"
                           RichText="{Binding SampleText}"/>
Emperor Eto
  • 2,456
  • 2
  • 18
  • 32