RichTextBox Binding is broken when text is manually modified or cleared

北慕城南 提交于 2020-04-07 08:09:30

问题


I have a RichTextBox bound to a string.

Using C# I generate a string that writes to it.

But if I want to manually change the text by clicking into the RichTextBox and deleting it with the backspace key, or pressing Enter to make a new line, the binding becomes broken and I can no longer programmatically write to it with the string a second time.


XAML

<RichTextBox x:Name="rtbScriptView" 
             Margin="11,71,280,56" 
             Padding="10,10,10,48"
             FontSize="14" 
             Grid.ColumnSpan="1" 
             VerticalScrollBarVisibility="Auto" 
             RenderOptions.ClearTypeHint="Enabled"
             Style="{DynamicResource RichTextBoxStyle}">
    <FlowDocument>
        <Paragraph>
            <Run Text="{Binding ScriptView_Text, 
                                Mode=TwoWay, 
                                UpdateSourceTrigger=PropertyChanged}" />
        </Paragraph>
    </FlowDocument>
</RichTextBox>

View Model

private string _ScriptView_Text;
public string ScriptView_Text
{
    get { return _ScriptView_Text; }
    set
    {
        if (_ScriptView_Text == value)
        {
            return;
        }

        _ScriptView_Text = value;
        OnPropertyChanged("ScriptView_Text");
    }
}

C#

ViewModel vm = new ViewModel();
DataContext = vm;

// Display a string in the RichTextBox

vm.ScriptView_Text = "This is a test."; // <-- This won't work if text is manually modified

回答1:


When you edit the RichTextBox, you alter the elements inside of the FlowDocument element. The element you have a binding on, is probably removed at some point during this editing. Have a look at RichtTextBox.Document.Groups to see what's happening when you edit the RichTextBox.

The default RichTextBox does not really support MVVM/Binding very well. You'd want to have a binding on the Document property, but this is not supported for the default RichTextBox. You could have a look here.

Or extend it yourself, something like this?:

BindableRichTextBox class

public class BindableRichTextBox : RichTextBox
{
    public static readonly DependencyProperty DocumentProperty = DependencyProperty.Register(nameof(Document), typeof(FlowDocument), typeof(BindableRichTextBox), new FrameworkPropertyMetadata(null, OnDocumentChanged));

    public new FlowDocument Document
    {
        get => (FlowDocument)GetValue(DocumentProperty);
        set => SetValue(DocumentProperty, value);
    }

    public static void OnDocumentChanged(DependencyObject obj, DependencyPropertyChangedEventArgs args)
    {
        var rtb = (RichTextBox)obj;
        rtb.Document = args.NewValue != null ? (FlowDocument)args.NewValue : new FlowDocument();
    }   
}

XAML

<controls:BindableRichTextBox Document="{Binding YourFlowDocumentObject, Mode=OneWay}"/>

Then you can get the string from the FlowDocument.




回答2:


Why you have to write this line. Please remove line after check.

if (_ScriptView_Text == value)
{
   return;
}


来源:https://stackoverflow.com/questions/55133899/richtextbox-binding-is-broken-when-text-is-manually-modified-or-cleared

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!