Search code examples
wpfdata-bindingwpf-controlsrichtextboxflowdocument

Binding the selected text of a RichTextBox to a property in the ViewModel


Hi i am working with WPF and using the MVVM pattern. So my problem is that i am trying to bind the selected text of a RichTextBox to a property in my ViewModel but i can't bind the Selection property.

So how can i do it?

Binding the Selection property of the RichTextBox to a property in my ViewModel is the way that i think is better to apply effects and decorations to the text.

If anyone knows a better way to know in the ViewModel the selected text of the RichTextBox, let me know. I am starting to learn about FlowDocuments and working with the RichTextBox so it's why i am a bit lost.

Thanks in advance!


Solution

  • You could use a Behavior:

    public class RichTextSelectionBehavior : Behavior<RichTextBox>
    {
        protected override void OnAttached()
        {
            base.OnAttached();
            AssociatedObject.SelectionChanged += RichTextBoxSelectionChanged;
        }
    
        protected override void OnDetaching()
        {
            base.OnDetaching();
            AssociatedObject.SelectionChanged -= RichTextBoxSelectionChanged;
        }
    
        void RichTextBoxSelectionChanged(object sender, System.Windows.RoutedEventArgs e)
        {
            SelectedText = AssociatedObject.Selection.Text;
        }
    
        public string SelectedText
        {
            get { return (string)GetValue(SelectedTextProperty); }
            set { SetValue(SelectedTextProperty, value); }
        }
    
        public static readonly DependencyProperty SelectedTextProperty =
            DependencyProperty.Register(
                "SelectedText",
                typeof(string),
                typeof(RichTextSelectionBehavior),
                new FrameworkPropertyMetadata(null, FrameworkPropertyMetadataOptions.BindsTwoWayByDefault, OnSelectedTextChanged));
    
        private static void OnSelectedTextChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
        {
            var behavior = d as RichTextSelectionBehavior;
            if (behavior == null)
                return;
            behavior.AssociatedObject.Selection.Text = behavior.SelectedText;
        }
    }
    

    XAML usage:

        <RichTextBox>
            <i:Interaction.Behaviors>
                <local:RichTextSelectionBehavior SelectedText="{Binding SelectedText}" />
            </i:Interaction.Behaviors>
        </RichTextBox>
    

    (where SelectedText is a string property on your ViewModel)