.NET GUI

.NET Community rund um alle Graphical User Interface (GUI) Themen.
Willkommen bei .NET GUI. Anmeldung | Registrieren | Hilfe | Impressum | Forumsregeln
in Suchen

Simples WPF PropertyGrid in 20 Minuten

Letzter Beitrag 05-13-2008 12:36 von joachimk. 0 Antworten.
Seite 1 von 1 (1 Treffer)
Beiträge sortieren: Zurück Weiter
  • 05-13-2008 12:36

    • joachimk
    • Top 25 Mitwirkender
      Männlich
    • Registriert am 04-11-2008
    • Salzburg, Austria
    • Beiträge 16
    • Punkte 250

    Simples WPF PropertyGrid in 20 Minuten

    Jeder der das WinForms PropertyGrid kennt, wird es in WPF vermissen. 
    Deshalb wird dieses kurze Tutorial zeigen wie man in kurzer Zeit ein eigenes PropertyGrid in WPF erzeugt.

    Achtung: Dies sollte keine fertige Komponente für den kommerziellen Einsatz sein. 
    Es zeigt lediglich eine sehr simple Methode Properties eines Objekts mit Reflection und Databinding in WPF anzuzeigen und zu verändern.
    Es soll auch nicht unbedingt als Ersatz für kommerzielle WPF PropertyGrid's (z.b. von MindScape) gesehen werden.
    Mehr als eine schnelle kleine Lösung für minimale Anforderungen.

    Dieses einfache PropertyGrid wird keine speziellen Editors für nicht-triviale Datentypen enthalten.
    Eine einfache TextBox soll hier zu Demonstrationszwecken reichen.
    Wir werden sehen dass durch die automatischen Konvertierungs-möglichkeiten von WPF nicht nur strings, sondern auch int, double, Color, SolidColorBrush, etc. in einer simplen TextBox bearbeitet werden können.

    Der PropertyGrid WPF Klon soll folgende Struktur haben:



    • TextBox zur Suche (Filterung) der Properties. Dies ist dann nützlich wenn man Klassen mit unzähligen Properties hat.
    • Ein Panel in dem die einzelnen Property-Name/Property-Value Paare aufgelistet werden. (Eingepackt in einen ScrollViewer)
    • Description TextBox in der die vom System.ComponentModel.DescriptionAttribute deklarierten Beschreibungen von Properties angezeigt werdegon (falls vorhanden)
    Zuerst werden wir mal die Oben abgebildete Struktur in XAML realisieren um einen Ausgangspunkt zu haben.
    Das sieht dann nach kurzer zeit ungefähr so aus :



    Als nächstes Machen wir uns ein UserControl das als Wrapper für die einzelnen PropertyItems dienen soll. 
    Dies beinhaltet in XAML grob gesagt nur einen TextBlock (für den Namen der Property) und eine TextBox (für den Wert der Property).
    Im Code-Behind definieren wir uns noch Properties für den Property-Namen/-Wert und -Beschreibung .

    Nun zur eigentlichen Arbeit:
    Unser PropertyGrid enthält das von WinForms her bekannte SelectedObject-Property das wir einfach auf das von uns gwünschte Objekt setzen das wir im PropertyGrid angezeigt haben möchten.
    Hier passiert nun die eigentliche Arbeit:

    foreach (PropertyDescriptor property in TypeDescriptor.GetProperties(value)){

    if (!property.IsBrowsable) continue; //nicht browsable. Ignorieren! PropertyItem currentProperty = new PropertyItem(); // currentProperty.PropertyName = property.Name;
    Binding b = new Binding(property.Name);
    b.Source = selectedObject;
    //OneWay Binding wenn readOnly, ansonsten TwoWay b.Mode = property.IsReadOnly ? BindingMode.OneWay : BindingMode.TwoWay;

    currentProperty.SetBinding(PropertyItem.PropertyValueProperty, b);
    currentProperty.OnActive += new EventHandler<DescriptionEventArgs>(currentProperty_OnActive);

    foreach (Attribute attribute in property.Attributes) //Attribute überprüfen { if (attribute.GetType() == typeof(DescriptionAttribute)){ //Beschreibung für Description TextBox currentProperty.PropertyDescription = ((DescriptionAttribute)attribute).Description;
    }
    if (attribute.GetType() == typeof(CategoryAttribute)) { //Kategorien wie aus WinForms bekannt. Not Implemented ;) currentProperty.PropertyCategory = ((CategoryAttribute)attribute).Category;
    }
    }

    PropertyPanel.Children.Add(currentProperty); //PropertyItem zu Panel hinzufügen }
    Das war Prinzipiell schon Alles. Was ist nun hier passiert?
    Wir iterieren erstmal über alle Properties die das Objekt, das wir an SelectedObjekt übergeben haben, enthält.
    Wenn es nicht als Browsable markiert ist (siehe System.ComponentModel.BrowsableAttribute) springen wir einfach zum nächsten.
    Andernfalls erstellen wir uns ein PropertyItem, setzen den Namen fest und erstellen ein Binding um die PropertyValue-Property mit dem eigentlichen Wert der Property zu verbinden.

    Und zum Schluss, bevor wir das PropertyItem zu unserem Panel hinzufügen, schauen wir uns noch die Attribute an um eine eventuell vorhandene Beschreibung des Attributs anzuzeigen.
    Zusätzlich wird noch auf das CategoryAttribute geprüft das einzelne Properties in Kategorien einteilen kann.
     Der Einfachheit halber habe ich das ganze jetzt jedoch mal weggelassen.
    Wenn wir das ganze nun Starten und irgend ein Objekt mit Properties der SelectedObject-Eigenschaft zuweisen
    (in diesem Falle eine Dummy Klasse mit verschiedenen Eigenschaften (strings,int, double, Color, SolidColorBrush, eines als nicht Browsable deklariert, etc),
    dann sieht das ganze wie folgt aus:



    Im oberen Screenshot sieht man nun wie unterschiedliche DatenTypen in Ihrer String-Repräsentation dargestellt werden.
    Um die Umwandlung zurück in das eigentliche Objekt muss man sich dank den Binding-Helpern in WPF nicht kümmern.
    Dies passiert ganz automatisch.
    Nun versehen wir unser PropertyGrid noch mit einem kleinen Style und dann erhalten wird folgendes Ergebnis:



    Um das einfache PropertyGrid zu verwenden eine Referenz zu PropertyGridDemo.dll hinzufügen , den NameSpace in XAML definieren:
    <Window x:Class="MyWindow"
    xmlns:ctl="clr-namespace:PropertyGridDemo;assembly=PropertyGridDemo"
    >


    danach kann das PropertyGrid wie folgt verwendet werden:
    z.b.
    <Grid>
        <ctl:PropertyGrid x:Name="propertyGrid"/>
    </Grid>


    und dann kann man in Code jedes Objekt als SelectedObject übergeben:

    //...
    this.propertyGrid.SelectedObject = myCustomObject;
    //...


    Die gesamte Solution kann HIER runtergeladen werden.



    http://blog.joachim.at
    • Beitragspunkte: 5
    • IP-Adresse ist Registriert
Seite 1 von 1 (1 Treffer)
Powered by Community Server (Commercial Edition)    Hosting powered by 69° media solutions