Die Anwendungsverwaltung besteht aus “Bereichen” auf der linken Seite und “Sektionen” innerhalb der Bereiche rechts.Die Bereiche werden durch die Auswahllistenwerte der Auswahlliste EnumSimpleConfigurationArea definiert; die Eigenschaft SortOrder dieser Auswahlliste bestimmt die Reihenfolge, in der die Bereiche angezeigt werden, die Eigenschaft Image das Bild. Diese Auswahlliste steht nur per Quellcode zur Verfügung und ist in der Auswahllistenverwaltung weder sichtbar noch änderbar. Erweitern Sie diese Auswahlliste per Programmierung mit eigenen Werten, um eigene Bereiche zu definieren. Der Bereich wird erst angezeigt, wenn auch eine Sektion implementiert ist.

Sektionen

Sektionen bestehen aus einem Kopfbereich und einem Inhaltsbereich. Der Inhaltsbereich kann über einen Mausklick auf den Kopfbereich auf- und zugeklappt werden.
Sektionen können einzeln in den Bearbeitungsmodus geschaltet werden. Hierfür muss bei der Implementierung eine entsprechende Schaltfläche vorgesehen werden. Es kann immer nur eine Sektion gleichzeitig im Bearbeitenmodus sein. Benutzer können jederzeit zwischen Sektionen und Bereichen wechseln, ohne dass aktuelle Änderungen verloren gehen.

Der Titel der Sektion, die sich im Bearbeitungsmodus befindet, wird zur leichteren Orientierung mit einem Stern gekennzeichnet, ebenso der Bereich, in dem sich diese Sektion befindet.

Die Implementierung einer Sektion ist nahezu identisch zu der eines freien Dialogs. Tatsächlich haben beide die gleiche technische Grundlage, weshalb in Sektionen die gleichen Einschränkungen für Maskensteuerelemente gelten wie in freien Dialogen.

Implementierung

Sektionsimplementierungen müssen die Basisklasse BA.Core.Configuration.Simple.SimpleConfigurationImplementationBase ableiten. Diese stellt einige virtuelle Methoden und Eigenschaften und eine abstrakte Methode zur Verfügung.

Die Eigenschaft Titel bezeichnet die prominent groß geschriebene erste Zeile des Kopfteils der Sektion, Summary die kleiner und blasser gehaltene zweite Zeile, die eine allgemeine Beschreibung dieser Sektion zurückgeben sollte. Visible sollte überschrieben werden, wenn die Sektion von gewissen Umständen abhängig nicht angezeigt werden soll. Die Standartimplementation von HandleAction liefert das Ergebnis mit der Aktion zurück, um die Sektion in den Lesemodus zu versetzen.

public abstract class SimpleConfigurationImplementationBase : UiImplementationBase, ISimpleConfigurationImplementation
{
    public virtual string Title { get; set; }

    public virtual bool Visible { get => true; }

    public virtual string Summary { get => null; }

    public abstract void CreateConfigurationContent(DevExFormModel formModel, HttpRequestBase request, ModelStateDictionary modelState, object bindObject);

    public virtual SimpleConfigurationActionResult HandleAction(HttpRequestBase request, ModelStateDictionary modelState, string buttonId, object bindObject, string namePrefix = "")
    {
        SimpleConfigurationActionResult result = new SimpleConfigurationActionResult
        {
            Action = "BA.Ui.SimpleConfiguration.Events.ReadSection",
            ButtonId = buttonId,
        };

        return result;
    }
}

Beispiel

Es folgt eine Beispielimplementation einer eigenen Sektion im Bereich “Adressen”:

[SimpleConfigurationImplementation("MyTestApp.AppManagement.Sections.MyTestSection", EnumSimpleConfigurationAreaExtension.AddressesGuid, "Meine Beispielsektion", 150)]
public class MyTestSection : SimpleConfigurationImplementationBase
{
    public override string Summary => "Dies ist die Kurzbeschreibung der Sektion";

    public override bool Visible => DateTime.Now.Month == 2;

    public override void CreateConfigurationContent(DevExFormModel formModel, HttpRequestBase request, ModelStateDictionary modelState, object bindObject)
    {
        if (!(bindObject is MySectionModel model))
            model = new MySectionModel();

        Controls.Add(new TextEditControl {
            Id = Guid.NewGuid(),
            Caption = "Mein Beispielfeld",
            HelpText = "Dies ist ein Beispielfeld für meine eigene Implementation einer Verwaltungssektion.",
            OrmFieldName = nameof(MySectionModel.MyTestValue);
        });

        formModel.DataSource = model;

        if (!formModel.IsReadonly)
        {
            formModel.AddButton(DialogButtonIds.CancelButton, "Abbrechen", false, "BA.Ui.SimpleConfiguration.Events.CancelSection");
            formModel.AddButton(DialogButtonIds.OkButton, "Wert verarbeiten", true);
        }
        else
            formModel.AddButton(DialogButtonIds.EditButton, "Bearbeiten", false, "BA.Ui.SimpleConfiguration.Events.EditSection");
    }

    public override SimpleConfigurationActionResult HandleAction(HttpRequestBase request, ModelStateDictionary modelState, string buttonId, object bindObject, string namePrefix = "")
    {
        SimpleConfigurationActionResult result = base.HandleAction(request, modelState, buttonId, bindObject, namePrefix);

        if (buttonId == DialogButtonIds.OkButton && bindObject is MySectionModel model)
        {
            if (!string.isNullOrEmpty(model.MyTestValue))
                Api.ClientCommunication.CreateInfo(Api.User.CurrentUserGuid(), "Wert wurde verarbeitet: " + model.MyTestValue);
            else
            {
                result.InvalidFields.Add(nameof(MySectionModel.MyTestValue));
                result.FieldMessages.Add("Sie müssen einen Wert eingeben.");
                result.Action = "";
            }
        }

        return result;
    }
}

Erläuterungen

Die Sektionsimplementierung wird durch das Attribut SimpleConfigurationImplementation gekennzeichnet. Der Konstruktor dieses Attributs bekommt als ersten Parameter eine eindeutige Id. Hier empfiehlt es sich, unter anderem den Namespace zu verwenden, der auch in Ihrem Projekt verwendet wird. Der zweite Parameter ist die Guid des Auswahllistenwertes, der den Bereich darstellt, in dem diese Sektion angezeigt werden soll (hier der Bereich “Addresses”). Der dritte Parameter definiert den Titel der Sektion, der angezeigt werden soll; hier kann auch eine Translation-Guid verwendet werden. Der letzte Parameter ist die Position der neuen Sektion innerhalb des Inhalts des Bereichs.

Die Klasse der Implementierung erbt von oben erwähnter Basisklasse SimpleConfgurationImplementationBase. Sie definiert im Beispiel eine Kurzbeschreibung und ist nur im Februar sichtbar.
Sie überschreibt die abstrakte Methode CreateConfigurationContent, die exakt so arbeitet, wie CreateDialogContent bei einem freien Dialog: Zunächst wird sich um das Model der Implementation gekümmert (es wird entweder aus dem Bind-Object zur Verfügung gestellt oder neu erstellt), dann werden Maskensteuerelemente instanziiert und zur globalen Variable Controls hinzugefügt, als Nächstes wird das Implementationsmodel an das formModel übergeben und schließlich eine konkrete (“Ok”) und zwei Standardschaltflächen hinzugefügt (“Abbrechen” und “Bearbeiten”).

Die Ok-Schaltfläche führt eine serverseitige Aktion durch, die hier über eine Implementierung der Methode HandleAction abgebildet wird. Ist der eingegebene Wert leer, wird eine entsprechende Validierungsmeldung ausgegeben, ist das Feld gefüllt, wird der Wert zusammen mit einer Meldung als Toaster-Nachricht ausgegeben.

Das verwendete Model MySectionModel enthält eine einzelne Texteigenschaft MyTestValue.