Seiten

Freitag, 15. April 2011

Datenbindung für den reichhaltigen Text eines RichTextBox-Steuerelements durch eine angefügte Abhängigkeitseigenschaft

Heute las ich einen Artikel in Delay's Blog über eine angefügte Abhängigkeitseigenschaft für ein WebBrowser-Steuerelement. Ich kann nur empfehlen, diesen Artikel mal zu lesen. Als ich diesen Artikel gelesen hatte, dachte ich mir, dass es cool wäre, wenn es etwas vergleichbares auch für die RichTextBox.Xaml-Eigenschaft gäbe. Die RichTextBox.Xaml-Eigenschaft ist eine einfache Eigenschaft vom Typ String und keine Abhängigkeitseigenschaft. Wenn dies eine Abhängigkeitseigenschaft wäre, so wäre es möglich, den Inhalt für eine RichTextBox über Datenbindung zu setzen.

Also habe ich mich hingesetzt und eine kleine Klasse geschrieben, mit deren Hilfe eine Datenbindung für den reichhaltigen Inhalt einer regulären RichTextBox möglich wird. Dabei wird die angefügte Abhängigkeitseigenschaft XamlSource verwendet.

Eine Verwendung dieser angefügten Abhängigkeitseigenschaft setzt natürlich voraus, dass man einen String hat, der Xaml-Code enthält, der von der RichTextBox.Xaml-Eigenschaft verstanden wird. Hierfür verwende ich einfach xml-Dateien, die zuvor mit meinem RichTextBox.Xaml Builder Addin erstellt wurden.

Nachfolgend stelle ich eine kleine Beispielanwendung vor und beschreibe kurz, wie einfach die Logik funktioniert.

Beispielanwendung

Hier ist zunächst einmal eine kleine Beispielanwendung.


Die obige Anwendung besteht aus einer ListBox, mit mehreren ListBoxItems, und aus einer einzelnen RichTextBox. Abhängig davon, welches ListBoxItem ausgewählt ist, wird in der RichTextBox ein anderer Inhalt dargestellt.

Die Logik der Beispielanwendung

Die Klasse XamlAP.vb stellt eine angefügte Abhängigkeitseigenschaft bereit. Dies ist die angefügte Abhängigkeitseigenschaft mit dem Namen XamlSource. Die Eigenschaft XamlSource nimmt als Wert den qualifizierten Dateinamen einer xml-Datei entgegen. Der nachfolgende Quellcode-Ausschnitt zeigt den PropertyChangedCallBack OnXamlSourcePropertyChanged der Klasse XamlAP.vb:

    Shared Sub OnXamlSourcePropertyChanged(ByVal d As DependencyObject, ByVal e As DependencyPropertyChangedEventArgs)

      Dim rtb As RichTextBox = CType(d, RichTextBox)

      If rtb Is Nothing Then

        Throw New NotSupportedException("XamlSource property only valid for RichTextBox instance.")

      End If

      Dim newSource As String = CStr(e.NewValue)

      If Not String.IsNullOrEmpty(newSource) Then

        rtb.Xaml = XElement.Load(newSource).ToString(SaveOptions.DisableFormatting)

        rtb.Selection.Select(rtb.ContentStart, rtb.ContentStart)

      End If

    End Sub

Hier wird der Xaml-Eigenschaft der RichTextBox als Wert der in einen String umgewandelte Inhalt einer xml-Datei zugewiesen. Die xml-Datei wurde zuvor mithilfe meines RichTextBox.Xaml Builder Addin erstellt. Wie man existierenden reichhaltigen Inhalt mit dem RichTextBox.Xaml Builder Addin so in xml konvertiert, dass das xml von der RichTextBox.Xaml-Eigenschaft als Xaml verstanden wird , habe ich hier beschrieben.

Um die angefügte Abhängigkeitseigenschaft verwenden zu können, muss der Namespace für die Klasse XamlAP.vb in MainPage.xaml referenziert werden:

<UserControl xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
            xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
            xmlns:silverlaw="clr-namespace:RtbAttachedXamlPropertyLab.SilverLaw"
            ...


Der Wert für XamlSource wird dann als Attribute der RichTextBox im Xaml gesetzt:

silverlaw:XamlAP.XamlSource="{Binding SelectedItem.Content, ElementName=fileList, Converter={StaticResource ItemConverter}}"

Im obigen Code wurde die XamlSource-Eigenschaft datengebunden. Die Datenbindung ist eine Elementeigenschaftsdatenbindung an die Content-Eigenschaft der ListBoxItems. Die ListBoxItems enthalten jeweils einen String-Wert als Content-Eigenschaft. Dieser String-Wert enthält jeweils einen beschreibenden Text für den reichhaltigen Inhalt, der in der RichTextBox dargestellt werden soll. Die Datenbindung nimmt hier also den beschreibenden Text der ListBoxItem entgegen. Damit die Datenbindung versteht, welche Datei jeweils abgerufen werden soll, wurde zusätzlich ein Converter implementiert. Hier ist der Quellcode dieses Converters:

Imports System.Windows.Data

Namespace SilverLaw


  Public Class ItemToFileNameConverter
    Implements IValueConverter

    Public Function Convert(ByVal value As Object,
                            ByVal targetType As System.Type,
                            ByVal parameter As Object,
                            ByVal culture As System.Globalization.CultureInfo) _
                          As Object Implements System.Windows.Data.IValueConverter.Convert

      Dim item As String = CStr(value)

      Dim returnValue As String = ""

      Select Case item

        Case Is = "OnXamlSourcePropertyChanged"

          returnValue = "0065.xml"

        Case Is = "XamlSourceProperty"

          returnValue = "0066.xml"

        Case Is = "MainPage.xaml"

          returnValue = "0067.xml"

        Case Is = "MainPage.xaml.vb"

          returnValue = "0068.xml"

        Case Is = "XamlAP.vb"

          returnValue = "0069.xml"

        Case Is = "ItemToFileNameConverter.vb"

          returnValue = "0070.xml"

      End Select

      Return returnValue

    End Function

    Public Function ConvertBack(ByVal value As Object,
                                ByVal targetType As System.Type,
                                ByVal parameter As Object,
                                ByVal culture As System.Globalization.CultureInfo) _
                              As Object Implements System.Windows.Data.IValueConverter.ConvertBack

      ' code

    End Function

  End Class


End Namespace

Die Methode Convert erhält den beschreibenden Text von einem ListBoxItem als Parameter übergeben. Dieser Wert wird ausgewertet und abhängig von diesem Wert wird der qualifizierte Name der zutreffenden xml-Datei zurückgegeben. Der qualifizierte Name der xml-Datei wird dann, wie weiter oben erwähnt, im PropertyChangedCallBack der angefügten Abhängigkeitseigenschaft ausgewertet.

Das war's. Bei jedem Klick auf ein ListBoxItem wird der betreffende Inhalt dargestellt.

Viel Spass damit!

Download: Vollständiger Quellcode des Beispielprojekts.

1 Kommentar:

  1. Hello,

    I read your article and it is very interesting. I am using Telerik richtextbox and it is very heavy for my xap file.
    I am interested to use your Add-in in my project. Can I bind the control to a database and set the path to xml document?

    Thanks for your help.
    Kam

    AntwortenLöschen