Es ist möglich, Teile der Bedienoberfläche während des Ablaufs von Hintergrundprozessen aktualisieren zu lassen. Ein gutes Beispiel, um dies zu beobachten ist die Serienkorrespondenz.
Beim Start der Serienkorrespondenz werden verschiedene Felder in den Lesemodus versetzt und bestimmte Teile der Maske im Verlauf der Verarbeitung regelmäßig aktualisiert, beispielsweise die Ansicht der Statusdatensätze oder beim Serienbrief die erstellte Briefdatei.

Um diese Funktionalität nutzen zu können, sind einige Voraussetzungen zu erfüllen:

  • Die Maske muss aktualisierbare Elemente beinhalten. Diese umfassen Detailansichten, Dateianhänge und Aktualisierungsgruppen.
  • Die Bereiche, die aktualisiert werden sollen, müssen in einem Form-Event-Handler „angemeldet“ werden.
  • Die im Hintergrundprozess verwendete Session muss so eingerichtet werden, dass beim Speichern von Objekten auch die Objekte im Orm-Cache aktualisiert werden. Dies kann zu Performance-Einbußen führen und sollte nur aktiviert werden, wenn es auch wirklich notwendig ist.
Sind diese Voraussetzungen erfüllt, ist der Hintergrundprozess in der Lage, die Oberfläche zu aktualisieren.

Anmelden der aktualisierbaren Bereiche

Die Anmeldung wird üblicherweise in der OnOpening Methode der Maskensteuerung vorgenommen, die natürlich dann in der entsprechenden Maske konfiguriert sein muss.
Das ganze passiert über ein sog. RefreshGroupModel:

RefreshGroupModel list = new RefreshGroupModel(parameters.FormModel);

Die Identifikation eines aktualisierbaren Bereichs erfolgt für die unterschiedlichen Bereichstypen auf unterschiedlichem Wege. Jeder dieser Wege beinhaltet aber die Angabe eines Gruppennamen, über welchen die entsprechenden Bereiche angesprochen werden können. Pro Gruppennamen können auch mehrere Bereiche angemeldet werden, so dass alle diese Bereiche beim entsprechenden Zugriff auf diesen Gruppennamen aktualisiert werden können.

Der einfachste Fall betrifft die Dateianhänge („attachment“ ist in diesem Fall der besagte Gruppenname):

list.AddAttachmentAreas(null, "attachment");

Der nächste Fall betrifft Aktualisierungsgruppen. Aktualisierungsgruppen haben keine festgelegte ID, so dass diese nur anhand ihres Inhalts bestimmt werden können. Hierfür muss also zur Identifizierung einer Aktualisierungsgruppe, die aktualisiert werden können soll, ein Feld angegeben werden, welches sich innerhalb besagter Gruppe befindet:

list.Add("Subject", null, false, "subject");

Es ist des Weiteren auch möglich, diese Aktualisierungsgruppen über in Feldern verwendete Relationen zu identifizieren, falls Maskensteuerelemente nicht auf ein konkretes Orm-Feld sondern eben mit einer Relation arbeiten:

list.Add(EnumRelationType.AuthorGuid, EnumAuthorRelationSubTypes.DefaultGuid, false, "properties");

Hier wird also der Bereich aktualisiert, in welchem sich das Feld zur Auswahl weiterer Bearbeiter befindet. Auf diese Art und Weise werden auch die Detailansichten innerhalb der aktuellen Maske zur Aktualisierung identifiziert:

list.Add(EnumRelationType.AuthorGuid, EnumAuthorRelationSubTypes.DefaultGuid, false, "detail"));

In diesem Beispiel werden alle Detailansichten einer Maske in die Gruppe “detail” aufgenommen.Hier sieht man auch deutlich die Anwendung des Gruppennamen. Am Ende werden hier unter „detail“ ALLE Detailansichten auf der Maske aktualisiert werden können.

IEnumerable<SingleDetailGridViewControl> detailViews = parameters.FormConfiguration.FlattenControls().OfType<SingleDetailGridViewControl>();
foreach (SingleDetailGridViewControl detailView in detailViews)
    list.Add(detailView.GetRelationDefinition().RelationTypeGuid.ToString(), null, false, "detail");

Sind alle Bereiche zur Aktualisierung identifiziert, müssen diese nur noch dem FormModel mitgeteilt werden, und die Anmeldung der Aktualisierungsbereiche ist somit abgeschlossen:

parameters.FormModel.RefreshGroups = list;

Verwendung in einem Hintergrundprozess

Die UI hält den Datensatz in einem Cache vor. Der Datensatz wird nur beim Umschalten in den Bearbeitenmodus neu geladen. Dieser cache wird normalerweise beim Speichern des Datensatzes im Backend nicht aktualisiert, daher kommen Änderungen von einem Hintergrundprozess normalerweise erst beim Benutzer an, wenn dieser den entsprechenden Datensatz neu lädt.

Es ist möglich, den Speichervorgang so zu erweitern, dass auch diese Cacheeinträge beim Speichern aktualisiert werden. Dies sollte nur aktiviert werden, wenn es für die UI-Aktualisierung notwendig ist.

Die Aktivierung sollte in der Session erfolgen, mit der die entsprechenden datensätze geladen wurden.

_UoW.UpdateCachedObjects(true);

Die eigentliche Aktualisierung erfolgt dann über die Client-Communication-API:

Api.ClientCommunication.SendMessage(new ClientCommunicationUpdateControls 
{ 
    Oid = [OID vom Zieldatensatz], 
    Keys = new List<string>() { "detail", "subject", "attachment"}
});

Hierbei wird die Oid des Datensatzes, dessen Maske aktualisiert werden soll, und eine Liste mit den Gruppenbezeichnern, der zu aktualisierenden Bereiche angegeben. Es ist nicht möglich mehrere Datensätze zu aktualisieren.