Richtextbox wpf Bindung


76

Um DataBinding von Documentin einem WPF durchzuführen RichtextBox, habe ich bisher 2 Lösungen gesehen, die von der abgeleitet werden RichtextBoxund eine hinzufügen sollen DependencyProperty, sowie die Lösung mit einem "Proxy".

Weder der erste noch der zweite sind zufriedenstellend. Kennt jemand eine andere Lösung oder stattdessen eine kommerzielle RTF-Steuerung, die DataBinding unterstützt ? Das Normale TextBoxist keine Alternative, da wir eine Textformatierung benötigen.

Irgendeine Idee?

Antworten:


24

Ich weiß, dass dies ein alter Beitrag ist, aber sehen Sie sich das Extended WPF Toolkit an . Es hat eine RichTextBox, die unterstützt, was Sie versuchen zu tun.


10
RichTextBox von Extended WPF Toolkit ist sehr langsam. Ich würde es nicht empfehlen.
Kapitán Mlíko

6
@ViktorLaCroix Sie wissen, dass dies nur die WPF RichTextBox mit einer zusätzlichen Eigenschaft ist, oder?
Sam

2
(weiter bis 2017 ...) Die wpf-Toolkits RichTextBox funktionieren sofort mit Rich Text oder Klartext. Es scheint auch viel schneller zu sein als die unten stehende
Hilfsmethode

2
Ihre kostenlose Lizenz ist nur für nichtkommerzielle Zwecke bestimmt. : /
Eric

103

Es gibt einen viel einfacheren Weg!

Sie können einfach eine angehängte DocumentXaml(oder DocumentRTF) Eigenschaft erstellen , mit der Sie das RichTextBoxDokument des Dokuments binden können . Es wird wie folgt verwendet, wobei Autobiographysich eine Zeichenfolgeeigenschaft in Ihrem Datenmodell befindet:

<TextBox Text="{Binding FirstName}" />
<TextBox Text="{Binding LastName}" />
<RichTextBox local:RichTextBoxHelper.DocumentXaml="{Binding Autobiography}" />

Voila! Vollständig bindbare RichTextBoxDaten!

Die Implementierung dieser Eigenschaft ist recht einfach: Wenn die Eigenschaft festgelegt ist, laden Sie die XAML (oder RTF) in eine neue FlowDocument. Wenn die FlowDocumentÄnderungen, den Eigenschaftswert aktualisieren.

Dieser Code sollte den Trick machen:

using System.IO;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;
public class RichTextBoxHelper : DependencyObject
{
    public static string GetDocumentXaml(DependencyObject obj)
    {
        return (string)obj.GetValue(DocumentXamlProperty);
    }

    public static void SetDocumentXaml(DependencyObject obj, string value)
    {
        obj.SetValue(DocumentXamlProperty, value);
    }

    public static readonly DependencyProperty DocumentXamlProperty =
        DependencyProperty.RegisterAttached(
            "DocumentXaml",
            typeof(string),
            typeof(RichTextBoxHelper),
            new FrameworkPropertyMetadata
            {
                BindsTwoWayByDefault = true,
                PropertyChangedCallback = (obj, e) =>
                {
                    var richTextBox = (RichTextBox)obj;

                    // Parse the XAML to a document (or use XamlReader.Parse())
                    var xaml = GetDocumentXaml(richTextBox);
                    var doc = new FlowDocument();
                    var range = new TextRange(doc.ContentStart, doc.ContentEnd);

                    range.Load(new MemoryStream(Encoding.UTF8.GetBytes(xaml)),
                          DataFormats.Xaml);

                    // Set the document
                    richTextBox.Document = doc;

                    // When the document changes update the source
                    range.Changed += (obj2, e2) =>
                    {
                        if (richTextBox.Document == doc)
                        {
                            MemoryStream buffer = new MemoryStream();
                            range.Save(buffer, DataFormats.Xaml);
                            SetDocumentXaml(richTextBox,
                                Encoding.UTF8.GetString(buffer.ToArray()));
                        }
                    };
                }
            });
}

Der gleiche Code kann für TextFormats.RTF oder TextFormats.XamlPackage verwendet werden. Für XamlPackage hätten Sie byte[]stattdessen eine Eigenschaft vom Typ string.

Das XamlPackage-Format bietet gegenüber einfachem XAML mehrere Vorteile, insbesondere die Möglichkeit, Ressourcen wie Bilder einzuschließen, und es ist flexibler und einfacher zu bearbeiten als RTF.

Es ist kaum zu glauben, dass diese Frage 15 Monate lang gestellt wurde, ohne dass jemand auf den einfachen Weg hingewiesen hat, dies zu tun.


6
@ Kelly, benutze DataFormats.Rtf, dies kann das Problem mit mehreren Richtextboxen lösen.
CharlieShi

16
Zweiwege funktioniert bei mir nicht (mit Rtf). Die range.ChangedVeranstaltung wird nie aufgerufen.
Patrick

1
@FabianBigler - Hallo - falls jemand das gleiche Problem hat - müssen Sie die xmlns: local-Deklaration zu Ihrer xaml-Datei hinzufügen, die auf den Namespace verweist, in dem dies verfügbar ist
Bartosz

2
Kann jemand ein Beispiel für den Wert der Autobiographie geben?
Longlostbro

1
@AntonBakulev Danke!
Longlostbro

17

Ich kann Ihnen eine ok - Lösung geben und man kann mit ihm gehen, aber bevor ich das tue , ich werde zu erklären versuchen , warum Dokument ist nicht ein DependencyPropertyzu beginnen.

Während der Lebensdauer eines RichTextBoxSteuerelements Documentändert sich die Eigenschaft im Allgemeinen nicht. Das RichTextBoxwird mit a initialisiert FlowDocument. Dieses Dokument wird angezeigt, kann auf viele Arten bearbeitet und entstellt werden, aber der zugrunde liegende Wert der DocumentEigenschaft bleibt die eine Instanz von FlowDocument. Daher gibt es wirklich keinen Grund, warum es ein DependencyProperty, dh bindbar sein sollte. Wenn Sie mehrere Standorte haben, die darauf verweisen FlowDocument, benötigen Sie den Verweis nur einmal. Da es sich überall um dieselbe Instanz handelt, sind die Änderungen für alle zugänglich.

Ich glaube nicht, dass FlowDocumentBenachrichtigungen über Dokumentänderungen unterstützt werden, obwohl ich nicht sicher bin.

Davon abgesehen ist hier eine Lösung. Bevor Sie beginnen, haben wir keine Benachrichtigungen, wenn sich die Document-Eigenschaft der Dokumentation ändert , da RichTextBoxsie nicht implementiert ist INotifyPropertyChangedund Document keine ist . Daher kann die Bindung nur OneWay sein.DependencyPropertyRichTextBox

Erstellen Sie eine Klasse, die die bereitstellt FlowDocument. Die Bindung erfordert die Existenz von a DependencyProperty, daher erbt diese Klasse von DependencyObject.

class HasDocument : DependencyObject
{
    public static readonly DependencyProperty DocumentProperty =
        DependencyProperty.Register("Document", 
                                    typeof(FlowDocument), 
                                    typeof(HasDocument), 
                                    new PropertyMetadata(new PropertyChangedCallback(DocumentChanged)));

    private static void DocumentChanged(DependencyObject obj, DependencyPropertyChangedEventArgs e)
    {
        Debug.WriteLine("Document has changed");
    }

    public FlowDocument Document
    {
        get { return GetValue(DocumentProperty) as FlowDocument; }
        set { SetValue(DocumentProperty, value); }
    }
}

Erstellen Sie ein Windowmit einem Rich-Text-Feld in XAML.

<Window x:Class="samples.Window1"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    Title="Flow Document Binding" Height="300" Width="300"
    >
    <Grid>
      <RichTextBox Name="richTextBox" />
    </Grid>
</Window>

Geben Sie Windowein Feld vom Typ an HasDocument.

HasDocument hasDocument;

Der Fensterkonstruktor sollte die Bindung erstellen.

hasDocument = new HasDocument();

InitializeComponent();

Binding b = new Binding("Document");
b.Source = richTextBox;
b.Mode = BindingMode.OneWay;
BindingOperations.SetBinding(hasDocument, HasDocument.DocumentProperty, b);

Wenn Sie die Bindung in XAML deklarieren möchten, müssen Sie Ihre HasDocumentKlasse von ableiten lassen, FrameworkElementdamit sie in den logischen Baum eingefügt werden kann.

Wenn Sie nun die DocumentEigenschaft ändern, ändern sich auch die HasDocumentRich-Text-Felder Document.

FlowDocument d = new FlowDocument();
Paragraph g = new Paragraph();
Run a = new Run();
a.Text = "I showed this using a binding";
g.Inlines.Add(a);
d.Blocks.Add(g);

hasDocument.Document = d;

3
+1 für die gute Antwort, aber ein Problem: Es gibt einen Grund, die Document-Eigenschaft zu einer Abhängigkeitseigenschaft zu machen, um die Verwendung des Steuerelements mit dem MVVM-Muster zu erleichtern.
David Veeneman

1
Guter Punkt, aber ich bin anderer Meinung; Nur weil MVVM in WPF-Apps weit verbreitet ist, bedeutet dies nicht, dass sich die API von WPF ändern sollte, nur um sie anzupassen. Wir arbeiten daran, wie wir können. Dies ist eine Lösung. Wir können uns auch einfach dafür entscheiden, unser Rich-Text-Feld in ein Benutzersteuerelement zu kapseln und eine Abhängigkeitseigenschaft im UserControl zu definieren.
Szymon Rozga

16

Ich habe den vorherigen Code ein wenig optimiert. Zuallererst Range.Changed hat bei mir nicht funktioniert. Nachdem ich range.Changed in richTextBox.TextChanged geändert habe, stellt sich heraus, dass der TextChanged-Ereignishandler SetDocumentXaml rekursiv aufrufen kann, sodass ich Schutz dagegen bereitgestellt habe. Ich habe auch XamlReader / XamlWriter anstelle von TextRange verwendet.

public class RichTextBoxHelper : DependencyObject
{
    private static HashSet<Thread> _recursionProtection = new HashSet<Thread>();

    public static string GetDocumentXaml(DependencyObject obj)
    {
        return (string)obj.GetValue(DocumentXamlProperty);
    }

    public static void SetDocumentXaml(DependencyObject obj, string value)
    {
        _recursionProtection.Add(Thread.CurrentThread);
        obj.SetValue(DocumentXamlProperty, value);
        _recursionProtection.Remove(Thread.CurrentThread);
    }

    public static readonly DependencyProperty DocumentXamlProperty = DependencyProperty.RegisterAttached(
        "DocumentXaml", 
        typeof(string), 
        typeof(RichTextBoxHelper), 
        new FrameworkPropertyMetadata(
            "", 
            FrameworkPropertyMetadataOptions.AffectsRender | FrameworkPropertyMetadataOptions.BindsTwoWayByDefault,
            (obj, e) => {
                if (_recursionProtection.Contains(Thread.CurrentThread))
                    return;

                var richTextBox = (RichTextBox)obj;

                // Parse the XAML to a document (or use XamlReader.Parse())

                try
                {
                    var stream = new MemoryStream(Encoding.UTF8.GetBytes(GetDocumentXaml(richTextBox)));
                    var doc = (FlowDocument)XamlReader.Load(stream);

                    // Set the document
                    richTextBox.Document = doc;
                }
                catch (Exception)
                {
                    richTextBox.Document = new FlowDocument();
                }

                // When the document changes update the source
                richTextBox.TextChanged += (obj2, e2) =>
                {
                    RichTextBox richTextBox2 = obj2 as RichTextBox;
                    if (richTextBox2 != null)
                    {
                        SetDocumentXaml(richTextBox, XamlWriter.Save(richTextBox2.Document));
                    }
                };
            }
        )
    );
}

Danke Lolo! Ich hatte auch Probleme mit der ursprünglichen Klasse. Das hat es für mich behoben. Riesige Zeitersparnis!
Mark Bonafe

Ich habe ein kleines Problem mit dieser Lösung gefunden. Es ist möglich, den Hook für TextChanged mehrmals festzulegen, wenn die Ansicht zwischen Aufrufen nicht geschlossen und neu erstellt wird. Ich erstelle einmal eine einzelne Ansicht und lade über eine Listenauswahl. Um dies zu beheben, habe ich eine typischere Methode zum Verknüpfen des TextChanged-Ereignisses erstellt. Dann hänge ich die Methode einfach aus, bevor ich sie einhänge. Dies stellt sicher, dass es nur einmal eingehakt wird. Kein Speicherverlust mehr (und kein langsam laufender Code mehr).
Mark Bonafe

Dies ist eine gute Arbeitslösung, aber meiner Erfahrung nach funktioniert es nicht mit mehreren Steuerelementen. Siehe meine Antwort .
Ajeeb.KP

Das ist großartig, danke. Funktioniert nicht, wenn Sie die Bindung programmgesteuert festlegen möchten. Ich gehe davon aus, dass sich der Thread, der die Bindung festlegt, von dem unterscheidet, der über XAML festgelegt wird. Daher musste ich eine SetDocumentXamlFirst-Methode hinzufügen, die den Rekursionsschutz nicht verwendet und nur manuell aufgerufen wird, wenn Sie den Wert zum ersten Mal festlegen möchten.
Stuzor

13
 <RichTextBox>
     <FlowDocument PageHeight="180">
         <Paragraph>
             <Run Text="{Binding Text, Mode=TwoWay}"/>
          </Paragraph>
     </FlowDocument>
 </RichTextBox>

Dies scheint bei weitem der einfachste Weg zu sein und wird in keiner dieser Antworten angezeigt.

Im Ansichtsmodell haben Sie nur die TextVariable.


1
In meinem Fall zeigt diese Lösung den Text der Text-Eigenschaft im Ansichtsmodell vertikal an, dh einen für jede Zeile.
Kintela

Es ist alles was ich brauchte. Vielen Dank!
Christopher Painter

Wie unterscheidet sich diese Lösung von einer regulären TextBox, die an die Text-Eigenschaft gebunden ist? Es macht den Zweck eines Rich-Text-Felds zunichte, das die Formatierung unterstützt und mit diesem Code effektiv ausgeschaltet wird.
Daap

Das war perfekt für mich. Je einfacher desto besser!
Gcdev

9

Warum nicht einfach einen FlowDocumentScrollViewer verwenden?


1
Dies ist die eigentliche Antwort.
Den

Sie können den Text in einem FlowDocumentScrollViewer
Eric

9

Erstellen Sie ein UserControl mit einer RichTextBox namens RTB. Fügen Sie nun die folgende Abhängigkeitseigenschaft hinzu:

    public FlowDocument Document
    {
        get { return (FlowDocument)GetValue(DocumentProperty); }
        set { SetValue(DocumentProperty, value); }
    }

    public static readonly DependencyProperty DocumentProperty =
        DependencyProperty.Register("Document", typeof(FlowDocument), typeof(RichTextBoxControl), new PropertyMetadata(OnDocumentChanged));

    private static void OnDocumentChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
    {
        RichTextBoxControl control = (RichTextBoxControl) d;
        FlowDocument document = e.NewValue as FlowDocument;
        if (document  == null)
        {
            control.RTB.Document = new FlowDocument(); //Document is not amused by null :)
        }
        else
        {
            control.RTB.Document = document;
        }
    }

Diese Lösung ist wahrscheinlich die "Proxy" -Lösung, die Sie irgendwo gesehen haben. Allerdings hat RichTextBox einfach kein Dokument als DependencyProperty. Sie müssen dies also auf andere Weise tun ...

HTH


In der letzten Zeile verwenden Sie "document", das einen Fehler in meinem Code auslöst. Aufgrund der statischen Methode muss es sich um eine Instanz von Document handeln. Aber was? Ich setze das Dokument, das ich über die DependencyProperty erhalte, das "Dokument". Durch Entfernen der "statischen" wird das letzte Argument der DependencyProperty unterbrochen. Also hier stecke ich fest. Die Helper-Klasse von oben zeigt auch keinen Text :(
ecth

1

Hier ist eine VB.Net-Version von Lolos Antwort:

Public Class RichTextBoxHelper
Inherits DependencyObject

Private Shared _recursionProtection As New HashSet(Of System.Threading.Thread)()

Public Shared Function GetDocumentXaml(ByVal depObj As DependencyObject) As String
    Return DirectCast(depObj.GetValue(DocumentXamlProperty), String)
End Function

Public Shared Sub SetDocumentXaml(ByVal depObj As DependencyObject, ByVal value As String)
    _recursionProtection.Add(System.Threading.Thread.CurrentThread)
    depObj.SetValue(DocumentXamlProperty, value)
    _recursionProtection.Remove(System.Threading.Thread.CurrentThread)
End Sub

Public Shared ReadOnly DocumentXamlProperty As DependencyProperty = DependencyProperty.RegisterAttached("DocumentXaml", GetType(String), GetType(RichTextBoxHelper), New FrameworkPropertyMetadata("", FrameworkPropertyMetadataOptions.AffectsRender Or FrameworkPropertyMetadataOptions.BindsTwoWayByDefault, Sub(depObj, e)
                                                                                                                                                                                                                                                                                                                    RegisterIt(depObj, e)
                                                                                                                                                                                                                                                                                                                End Sub))

Private Shared Sub RegisterIt(ByVal depObj As System.Windows.DependencyObject, ByVal e As System.Windows.DependencyPropertyChangedEventArgs)
    If _recursionProtection.Contains(System.Threading.Thread.CurrentThread) Then
        Return
    End If
    Dim rtb As RichTextBox = DirectCast(depObj, RichTextBox)
    Try
        rtb.Document = Markup.XamlReader.Parse(GetDocumentXaml(rtb))
    Catch
        rtb.Document = New FlowDocument()
    End Try
    ' When the document changes update the source
    AddHandler rtb.TextChanged, AddressOf TextChanged
End Sub

Private Shared Sub TextChanged(ByVal sender As Object, ByVal e As TextChangedEventArgs)
    Dim rtb As RichTextBox = TryCast(sender, RichTextBox)
    If rtb IsNot Nothing Then
        SetDocumentXaml(sender, Markup.XamlWriter.Save(rtb.Document))
    End If
End Sub

Klasse beenden


0

Diese VB.Net-Version funktioniert für meine Situation. Ich habe das Thread-Sammlungssemaphor entfernt und stattdessen RemoveHandler und AddHandler verwendet. Da ein FlowDocument jeweils nur an eine RichTextBox gebunden werden kann, überprüfe ich, ob IsLoaded = True der RichTextBox ist. Beginnen wir damit, wie ich die Klasse in einer MVVM-App verwendet habe, die ResourceDictionary anstelle von Window verwendet.

    ' Loaded and Unloaded events seems to be the only way to initialize a control created from a Resource Dictionary
' Loading document here because Loaded is the last available event to create a document
Private Sub Rtb_Loaded(ByVal sender As System.Object, ByVal e As System.Windows.RoutedEventArgs)
    ' only good place to initialize RichTextBox.Document with DependencyProperty
    Dim rtb As RichTextBox = DirectCast(sender, RichTextBox)
    Try
        rtb.Document = RichTextBoxHelper.GetDocumentXaml(rtb)
    Catch ex As Exception
        Debug.WriteLine("Rtb_Loaded: Message:" & ex.Message)
    End Try
End Sub

' Loaded and Unloaded events seems to be the only way to initialize a control created from a Resource Dictionary
' Free document being held by RichTextBox.Document by assigning New FlowDocument to RichTextBox.Document. Otherwise we'll see an of "Document belongs to another RichTextBox"
Private Sub Rtb_Unloaded(ByVal sender As System.Object, ByVal e As System.Windows.RoutedEventArgs)
    Dim rtb As RichTextBox = DirectCast(sender, RichTextBox)
    Dim fd As New FlowDocument
    RichTextBoxHelper.SetDocumentXaml(rtb, fd)
    Try
        rtb.Document = fd
    Catch ex As Exception
        Debug.WriteLine("PoemDocument.PoemDocumentView.PoemRtb_Unloaded: Message:" & ex.Message)
    End Try
End Sub

Public Class RichTextBoxHelper
    Inherits DependencyObject

    Public Shared Function GetDocumentXaml(ByVal depObj As DependencyObject) As FlowDocument
        Return depObj.GetValue(DocumentXamlProperty)
    End Function

    Public Shared Sub SetDocumentXaml(ByVal depObj As DependencyObject, ByVal value As FlowDocument)
        depObj.SetValue(DocumentXamlProperty, value)
    End Sub

    Public Shared ReadOnly DocumentXamlProperty As DependencyProperty = DependencyProperty.RegisterAttached("DocumentXaml", GetType(FlowDocument), GetType(RichTextBoxHelper), New FrameworkPropertyMetadata(Nothing, FrameworkPropertyMetadataOptions.AffectsRender Or FrameworkPropertyMetadataOptions.BindsTwoWayByDefault, Sub(depObj, e)
                                                                                                                                                                                                                                                                                                                                   RegisterIt(depObj, e)
                                                                                                                                                                                                                                                                                                                               End Sub))


    Private Shared Sub RegisterIt(ByVal depObj As System.Windows.DependencyObject, ByVal e As System.Windows.DependencyPropertyChangedEventArgs)
        Dim rtb As RichTextBox = DirectCast(depObj, RichTextBox)
        If rtb.IsLoaded Then
            RemoveHandler rtb.TextChanged, AddressOf TextChanged
            Try
                rtb.Document = GetDocumentXaml(rtb)
            Catch ex As Exception
                Debug.WriteLine("RichTextBoxHelper.RegisterIt: ex:" & ex.Message)
                rtb.Document = New FlowDocument()
            End Try
            AddHandler rtb.TextChanged, AddressOf TextChanged
        Else
            Debug.WriteLine("RichTextBoxHelper: Unloaded control ignored:" & rtb.Name)
        End If
    End Sub

    ' When a RichTextBox Document changes, update the DependencyProperty so they're in sync.
    Private Shared Sub TextChanged(ByVal sender As Object, ByVal e As TextChangedEventArgs)
        Dim rtb As RichTextBox = TryCast(sender, RichTextBox)
        If rtb IsNot Nothing Then
            SetDocumentXaml(sender, rtb.Document)
        End If
    End Sub

End Class

0

Die meisten meiner Bedürfnisse wurden durch diese Antwort https://stackoverflow.com/a/2989277/3001007 von krzysztof befriedigt . Aber ein Problem mit diesem Code (mit dem ich konfrontiert war) war, dass die Bindung nicht mit mehreren Steuerelementen funktioniert. Also habe ich mich _recursionProtectionmit einer Guidbasierten Implementierung verändert. Es funktioniert also auch für mehrere Steuerelemente im selben Fenster.

 public class RichTextBoxHelper : DependencyObject
    {
        private static List<Guid> _recursionProtection = new List<Guid>();

        public static string GetDocumentXaml(DependencyObject obj)
        {
            return (string)obj.GetValue(DocumentXamlProperty);
        }

        public static void SetDocumentXaml(DependencyObject obj, string value)
        {
            var fw1 = (FrameworkElement)obj;
            if (fw1.Tag == null || (Guid)fw1.Tag == Guid.Empty)
                fw1.Tag = Guid.NewGuid();
            _recursionProtection.Add((Guid)fw1.Tag);
            obj.SetValue(DocumentXamlProperty, value);
            _recursionProtection.Remove((Guid)fw1.Tag);
        }

        public static readonly DependencyProperty DocumentXamlProperty = DependencyProperty.RegisterAttached(
            "DocumentXaml",
            typeof(string),
            typeof(RichTextBoxHelper),
            new FrameworkPropertyMetadata(
                "",
                FrameworkPropertyMetadataOptions.AffectsRender | FrameworkPropertyMetadataOptions.BindsTwoWayByDefault,
                (obj, e) =>
                {
                    var richTextBox = (RichTextBox)obj;
                    if (richTextBox.Tag != null && _recursionProtection.Contains((Guid)richTextBox.Tag))
                        return;


                    // Parse the XAML to a document (or use XamlReader.Parse())

                    try
                    {
                        string docXaml = GetDocumentXaml(richTextBox);
                        var stream = new MemoryStream(Encoding.UTF8.GetBytes(docXaml));
                        FlowDocument doc;
                        if (!string.IsNullOrEmpty(docXaml))
                        {
                            doc = (FlowDocument)XamlReader.Load(stream);
                        }
                        else
                        {
                            doc = new FlowDocument();
                        }

                        // Set the document
                        richTextBox.Document = doc;
                    }
                    catch (Exception)
                    {
                        richTextBox.Document = new FlowDocument();
                    }

                    // When the document changes update the source
                    richTextBox.TextChanged += (obj2, e2) =>
                        {
                            RichTextBox richTextBox2 = obj2 as RichTextBox;
                            if (richTextBox2 != null)
                            {
                                SetDocumentXaml(richTextBox, XamlWriter.Save(richTextBox2.Document));
                            }
                        };
                }
            )
        );
    }

Lassen Sie mich der Vollständigkeit halber noch einige Zeilen aus der ursprünglichen Antwort https://stackoverflow.com/a/2641774/3001007 von ray-burns hinzufügen . So verwenden Sie den Helfer.

<RichTextBox local:RichTextBoxHelper.DocumentXaml="{Binding Autobiography}" />

-1

Leute, warum sich mit all dem Faff beschäftigen. Das funktioniert perfekt. Kein Code erforderlich

<RichTextBox>
    <FlowDocument>
        <Paragraph>
            <Run Text="{Binding Mytextbinding}"/>
        </Paragraph>
    </FlowDocument>
</RichTextBox>

1
In meinem Fall funktioniert es nicht ohne das Tag 'FlowDocument'.
Klaonis

TextDie Eigenschaft von Runist keine Abhängigkeitseigenschaft, daher wird diese nicht einmal kompiliert. Nur Abhängigkeitseigenschaften unterstützen eine solche Bindung.
Hoffnungslos

Das war genau das, was ich brauchte.
Christopher Painter
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.