Erweiterte Programmierung


Mit Triggern programmieren Sie das dynamische Verhalten eines grafischen Elementes.

Für jede grafische Eigenschaft, die Sie mit Triggern beeinflussen möchten, sollten Sie zuerst den Initial-Wert im "Style.Setters-Collection" per Setter setzen (siehe voriges Kapitel).

Um Trigger zu definieren, öffnen Sie das Triggerfenster per Kontext-Kommando "Edit Style Trigger":

 


Verwenden Sie Datentrigger, um die Präsentation eines grafischen Elements zu ändern, wenn sich Daten im Modell geändert haben.

Übertragen auf das iPlus-Framework bedeutet dies: Wenn sich der Wert von einer oder mehreren Eigenschaften einer ACComponent-Instanz  geändert haben, soll sich die Darstellung an der grafischen Oberfläche ändern.
Eine Lösungsmöglichkeit ist der Einsatz von Konvertern, auf die im  Kapitel "Eigenschaften setzen und konvertieren" eingegangen wurde. Konverter haben den Nachteil, dass dazu Methoden programmiert und aufgerufen werden müssen und somit die Dynamisierung nicht rein deklarativ im XAML-Code erfolgt.
Mit Datentriggern kann eine Dynamisierung rein deklarativ erfolgen und ist daher die bessere Wahl.

Wir nehmen dazu erneut unser Rechteckbeispiel und führen eine Farbänderung des Rechtecks durch mittels Datentriggern:

  1. Drücken Sie die Taste "Data" um einen Datentrigger dem Style hinzuzufügen (1).
  2. Drücken Sie die Taste "One data item" wenn die Farbänderung nur von einer Eigenschaft aus dem Modell (ACComponent) sein soll (2).
  3. Ziehen Sie per "Drag & Drop" die entsprechende Eigenschaft auf das VBContent-Textfeld (3). In unserem Beispiel ist es die SensorState-Eigenschaft des NOT-AUS-Schalters (bzw. Sensors).
  4. Wählen Sie den Wert der Eigenschaft aus, bei dem der Datentrigger aktiv werden soll, um seine Präsentationsänderungsaufgaben auszuführen, die entweder in seiner Setters-Liste oder den Action-Listen eingetragen sind.

 

Im Beispiel möchten wir vorerst nur mit der Setters-Liste arbeiten, weil für Actions das seperate Kapitel "Animationen" gewidmet ist.
Um Setter hinzuzufügen, wechseln Sie in die Registerkarte "Setter" und fügen per "Add"-Taste die grafischen Eigenschaften hinzu, die der Datentrigger verändern soll:

 

Schließen Sie das Trigger-Fenster und wechseln in den XAML-Editor. Es wurde folgender Code generiert: 

 

Das Feld "Binding" des Datatriggers wurde an die ACUrl der SensorState-Eigenschaft gebunden. Ein Datatrigger kann nur einen Wert binden. Müssen mehrere Eigenschaften berücksichtigt werden, gibt es zwei unterschiedliche Möglichkeiten. Entweder Sie verwenden

auf die in den folgenden Abschnitten näher eingegangen wird.

 


Mit Multidatatriggern können mehrere Eigenschaftswerte gebunden werden.

In unserem Beispiel möchten wir zusätzlich noch eine weitere Eigenschaft berücksichtigen, die Einfluss auf die Farbänderung des Rechtecks haben soll.

  1. Dazu drücken Sie die Taste "Multi-Data", um einen Multidatatrigger hinzuzufügen (1).
  2. Drücken Sie die Taste "One data item" (Für einfache Bindings) (2).
  3. Ziehen per "Drag & Drop" die Eigenschaften in die Listbox, die der Multidatatrigger berücksichtigen soll. In unserem Beispiel sind es die SensorState-Eigenschaft des NOT-AUS-Schalters als auch die RunState-Eigenschaft (Laufmeldung) eines Motors (3). Für jede Eigenschaft definieren Sie den Wert der Eigenschaft die vom Multidatatrigger ausgewertet werden soll damit der Trigger ausgelöst wird.
  4. Wechseln Sie in die "Setter"-Registerkarte und fügen per "Add"-Taste die grafischen Eigenschaften hinzu, die der Datentrigger verändern soll.

 

Schließen Sie das Trigger-Fenster und wechseln in den XAML-Editor. Es wurde folgender Code generiert: 

 

Im Multidatatrigger wurde die Conditions-Liste mit zwei Conditions befüllt. Jede Condition wurde an eine Eigenschaft aus dem Modell (ACComponent) gebunden. Erst wenn bei beiden gebundenen Eigenschaften der unter Value gesetzte Wert eingetreten ist, dann wird der Multidatatrigger ausgelöst. Conditions sind daher immer "UND"-Verknüpft!

Diese UND-Verknüpfung ist gleichzeitig auch ein Nachteil von Multidatatriggern, wenn man stattdessen eine OR-Verknüpfung oder komplexere logische Ausdrücke benötigt. Ein Ausweg dafür sind Datatrigger mit Multibindings und Expressions.


Mit einem Datatrigger in Kombination mit Multibindings und Expressions, können gebundene Eigenschaften mit komplexen logischen Ausdrücken ausgewertet werden.

Für unser Rechteckbeispiel gehen wir gleich vor wie für einfache Datatrigger (siehe zweiten Abschnitt "Datentrigger editieren").

  1. Drücken Sie die Taste "Data" um einen Datentrigger dem Style hinzuzufügen (1).
  2. Drücken Sie die Taste "More data items" weil die Farbänderung nur von mehreren Eigenschaften aus dem Modell (ACComponent) abhängig sein soll (2).
  3. Ziehen Sie per "Drag & Drop" die entsprechenden Eigenschaften auf in die Listbox. In unserem Beispiel sind es die SensorState-Eigenschaft des NOT-AUS-Schalters (3)
  4. als auch die RunState-Eigenschaft (Laufmeldung) eines Motors (4).
  5. Öffnen Sie das Editierfenster für den Converter und wählen Sie den Modus "Expression" aus (5).
  6. Expression bedeutet, dass für die Auswertung der gebundenen Werte Lambda-Expressions verwendet werden sollen. Das Parsing der Lambda-Expressions erfolgt mit der Library "simproexpr". Technisch wird die Lambda-Expression in eine sogenannte anonyme Funktion übersetzt, die entsprechend der Anzahl der gebundenen Eigenschaften im Multibinding die gleiche Anzahl von Parametern in der Parameterliste der Methodensignatur besitzt. In unserem Beispiel ist die Signatur
    (PANotifyState p1, Boolean p2) =>
    Anschließend programmieren Sie den logischen Ausdruck (6). Für mehr Informationen lesen Sie dazu die Anleitung des Expression-Parsers.
  7. Das Ergebnis der Lambda-Expression sollte immer ein boolescher Wert sein. Im Feld Value geben Sie an ob der Trigger bei false oder true auslösen soll (7).

 

 

Schließen Sie das Trigger-Fenster und wechseln in den XAML-Editor. Es wurde folgender Code generiert:  

 

Im Wesentlichen ähnelt der XAML-Code dem Code aus dem Abschnitt "Eigenschaften setzen und konvertieren" weil zum einen Multibinding in Kombination mit Konvertern verwendet wurde. Der Unterschied ist jedoch, dass die Logik mittels der Expression-Syntax (Ausdruck in der Konvertereigenschaft "Expression") im XAML-Code steckt und die Farbänderung mittels Setter-Objekten. Die Dynamisierung ist daher rein deklarativ ohne die Verwendung von Methodenaufrufen.

Expressions kommen jedoch dann an die Grenze, wenn nicht logische Ausdrücke allein nicht ausreichen und z.B. Datenbankzugriffe gemacht werden müssen oder völlige Programmierfreiheit erforderlich ist.

In diesem Fall wird die "gip.core.layoutengine.ConverterBase"-Klasse nicht mit Expressions eingesetzt, sondern mit Methoden-Aufrufen:


Verwenden Sie Methodenaufrufe, wenn Expressions an Ihre Grenzen kommen oder Sie Ausdrücke an verschiedenen Stellen wiederverwenden wollen.

Deklarieren Sie entweder eine clientseitige Methode in Ihrer Assembly oder verwenden Sie Skriptmethoden. In beiden Fällen muss die Signatur der Methode so viele Übergabeparameter haben wie die Anzahl der gebundenen Eigenschaften im Multibinding.

In unserem Beispiel würde die Skriptmethode folgendermaßen aussehen:

 

  1. Drücken Sie die Taste "Neue Client-Methode" (1).
  2. Geben Sie der Methode einen Namen in der Registerkarte "Methodeinfo" (2).
  3. Programmieren Sie die Skriptmethode aus (3). In unserem Beispiel haben wir sie "ConvertExampleA" genannt.

Wechseln Sie nun in das Design wo Sie die Methode verwenden möchten und öffnen das Triggerfenster um einen Datentrigger anzulegen. Gehen Sie vor wie im vorigen Abschnitt beschrieben und wiederholen die Schritte 1-4. Anstatt Schritt 5, bei dem Lambda-Expressions deklariert wurden benötigen wir nun den Methodenaufruf. Dazu öffnen Sie den Expander "Methoden" und ziehen die Methode "ConvertExampleA" per "Drag & Drop" auf den Konverter:

 

Im Konverter-Editor-Fenster wurde der Mode auf "ScriptEngine" gesetzt und in der Url steht die Adresse zum Methodenaufruf. Schließen Sie das Trigger-Fenster und wechseln in den XAML-Editor. Es wurde folgender Code generiert:  

 

Im Wesentlichen ähnelt der XAML-Code dem Code aus dem Abschnitt "Eigenschaften setzen und konvertieren" weil zum einen Multibinding in Kombination mit Konvertern verwendet wurde. Der Unterschied ist jedoch, dass die Methode keine Instanz aus dem System.Windows oder System-Drawing Namespace zurückgibt. Somit ist eine Trennung zwischen Model und Präsentation hergestellt entsprechend des MVVM-Patterns, weil die Präsentation deklarativ per Setter-Objekten erfolgt.