VBDesign ist ein ContentControl, das ebenfalls wie VBVisual IVBContent implementiert.
VBDesigns dienen zum Laden und Anzeigen von Designs der Kategorie Hauptansicht (DUMain) und Teilansicht (DULayout). Hauptansichten und Teilansichten werden für Businessobjekte benötigt. Wenn ein Businessobjekt gestartet wird, dann wird vom iPlus-Framework zuerst ein Wurzel-VBDesign generiert und danach die Hauptansicht vom XAML-Parser geladen. Die Hauptansicht wird anschließend der Content-Eigenschaft des Wurzel-VBDesigns zugewiesen und der Datenkontext mit dem neuen Businessobjekt gesetzt. Zuletzt wird dann das Wurzel-VBDesign in den Logical-Tree eingehängt, damit es visuell sichtbar wird.
Entsprechend dem Schachtelungsprinzip von Designs, ist es nicht sinnvoll das gesamte Layout (XAML-Code) in eine Hauptansicht zu packen. Stattdessen sollten Hauptansichten weitere Teilansichten (Unterdesigns) laden, indem im XAML-Code "<VBDesign>"-Elemente deklariert und in der VBContent-Property der Name (ACIdentifier) des Unterdesigns mit einem vorangestellten Asterisk "*" angegeben wird:
e.g. <Grid>...
<vb:VBDesign VBContent="*MyNameOfSubdesign"/>
...</Grid>
Wird kein Asterisk vorangestellt, dann wird der VBContent als ACUrl interpretiert und es erfolgt eine Auflösung des Pfades für ein Databinding. Die Eigenschaft im Businessobjekt, die gebunden werden soll, sollte vom Typ ACClassDesign sein. Somit kann das Businessobjekt per PropertyChanged-Event das VBDesign benachrichtigen, dass ein anderes Design geladen werden soll, das vom Businessobjekt selbst bereitgestellt wird. Mit dieser Technik können Sie z.b. einen Layoutwechsel zur Laufzeit im Stile eines Wizards umsetzen.
Wenn Sie VBDesigns im XAML-Code von Teilansichten platzieren, laden Sie wiederum weitere Teilansichten. Achten Sie darauf, dass eine Teilansicht sich nicht selbst erneut lädt. Eine Rekursionsüberprüfung gibt es nicht. Stattdessen wird eine StackOverflow-Exception vom .NET-Framework geworfen.
Beim Laden von Teilansichten wird der Datenkontext nicht geändert, sondern er wird über den Logical-Tree vom Wurzel-VBDesign geerbt. Den Datenkontext ändern Sie selbst, indem Sie ein Binding zu einer anderen Eigenschaft deklarieren.
Untergeordnete Geschäftsobjekte
Entsprechend des Kompositionsmusters, können Businessobjekte wieder Kind-Businessobjekte besitzen. Businessobjekte werden normalerweise Just-In-Time geladen, wenn sie benötigt werden. Ein Kind-Businessobjekt kann auch per VBDesign instanziiert und als Unteransicht ("Plugin") in das Design des Eltern-Businessobjekt integriert werden. Dies erreichen Sie mit dem <VBInstanceInfo>-Element:
...
<vb:VBDesign VBContent="*Mainlayout">
<vb:VBInstanceInfo Key="BSOAlarmMessengerConfig_Child"
ACIdentifier="BSOAlarmMessengerConfig_Child"
SetAsDataContext="True"
SetAsBSOACComponet="True"
AutoStart="True">
</vb:VBInstanceInfo>
</vb:VBDesign>
...
Innerhalb eines VBDesigns, können mehrere VBInstanceInfo's deklariert werden.
In der Eigenschaft ACIdentifier geben Sie den Namen des Kind-Businessobjektes an, das Sie zuvor in der Entwicklungsumgebung im Klassenbaum hinzugefügt haben. Im Feld Key geben Sie am besten denselben Namen an (Er dient zu eindeutigen Identifizierung der IntanceInfo-Instanz im Logical-Tree). Wird die Eigenschaft SetAsDataContext auf True gesetzt, dann wird der Datenkontext des VBDesigns mit dem Kind-Businessobjekt gesetzt. Die AutoStart-Eigenschaft gibt an, ob das Kind-Businessobjekt zur Laufzeit instanziiert werden soll, falls es noch nicht vorhanden ist.
Wichtig: Mit dem Ändern des Datenkontextes per SetAsDataContext, ändern Sie auch den Kontext zur Suche des Designs, das in der VBContent-Eigenschaft angegeben ist. Im obigen Beispiel wird das Design "Mainlayout" vom Kind-Businessobjekt gesucht und nicht das vom Eltern-BSO in dem der obige XAML-Code deklariert ist.
Besonderheit: BSOACComponent
Wenn Sie gut aufgepasst haben, werden Sie sich gefragt haben, wie kann eigentlich die relative Adressierung des Kind-Businessobjektes in VBInstanceInfo funktionieren, wenn es möglich ist, den Datenkontext durch ein Binding im Design des Eltern-Businessobjekts zu verändern?
Sie haben recht, dies funktioniert auch nicht und deswegen ist in der Basisklasse VBDesignBase des VBDesign's die Eigenschaft BSOACComponent deklariert:
public static readonly DependencyProperty BSOACComponentProperty =
ContentPropertyHandler.BSOACComponentProperty.AddOwner(
typeof(VBDesignBase),
new FrameworkPropertyMetadata(null,
FrameworkPropertyMetadataOptions.Inherits,
new PropertyChangedCallback(OnDepPropChanged))
);
Diese Eigenschaft ist wie auch die FrameworkElement.DataContext-Property vererbbar im Logical-Tree. Beim Laden vom Root-VBDesign wird diese Eigenschaft ebenfalls gesetzt und darüber können dann Kind-Businessobjekte relativ adressiert werden - auch bei Verlust des Datenkontextes. Aus diesem Grunde sollten Sie auch im VBInstanceInfo-Element die Eigenschaft "SetAsBSOACComponent" auf True setzen wie Sie es im obigen Beispiel sehen können.