Es wird eine neue C# Klasse benötigt. Typischerweise wird diese im Ordner „Configuration\Navigation\ClientAction“ abgelegt. Die Basisklasse ist ClientActionBase
, und es müssen drei Attribute gesetzt werden. Wie alle anderen Konfigurationen muss auch diese serialisier bar sein, mit Toolbox
wird die Aktion in der Toolbox für die Navigationen registriert und mit ControlFilter
wird die Aktion nur für die Ribbon bar sichtbar gemacht.
[Serializable]
[Toolbox(EnumConfigurationType.NavigationConfigurationGuid, true)]
[ControlFilter("NavigationConfigurationType", ExpressionType.Equal, EnumNavigationConfigurationType.RibbonNavigationGuid, EnumControlFilterApplyState.IfPositive)]
public class ClientActionMyAction : ClientActionBase { }
Im Konstruktor werden die wichtigsten Eigenschaften einer Aktion festgelegt (Siehe Beispiel). Folgende Punkte müssen beachtet werden.
- Anstatt Klartext sollte bei den Eigenschaften „ToolboxName“, „Caption“, „ToolboxGroupName“ und „DesignerHintText“ immer eine Translation Guid benutzt werden.
- Der „ControlInitName“ sollte Eindeutig sein. Also immer mit eigenen Präfixen arbeiten.
- Für „Id“ muss immer eine eigene Guid erzeugt werden.
public ClientActionMyAction() : base()
{
ToolboxName = "Meine Aktion";
Caption = "Meine Aktion";
ControlInitName = "TrainingMyAction";
ToolboxGroupName = "Training Aktionen"; // Translation Guid verwendbar
Id = new Guid("[INSERT ACTION GUID]");
Icon = "projector";
IconName = Icon;
DesignerHintText = "Meine Aktion tut genau das, was gewünscht wird."; // Translation Guid verwendbar
VisibilityForParentTypes.Add(EnumActionVisibleForParentType.Form);
}
Mit dem Objekt VisibilityForParentTypes
kann man steuern für welche Objekte (Masken / Ansichten) die eigene Aktion prinzipiell verwendet werden kann.
Damit ist schon eine eigene Aktion so implementiert, dass sie im Designer konfiguriert werden kann.
Die registrierte Aktion kann nun in dem Konstruktor der C# Klasse hinterlegt werden.
AdditionalClientData.AddOrUpdate("ActionMethodId", "BA.Training.ClientActionMyAction");
Damit ist das Grundgerüst einer konfigurierbaren Aktion erstellt.
Drag & Drop Regel
Bei jedem Steuerelement, welches im Designer zur Konfiguration genutzt werden soll, muss man darauf achten, dass die Drag & Drop Regeln korrekt gesetzt sind. Näheres dazu findet man in dem speziellen Kapitel.
Meistens werden für Aktionen auf Basis von ClientActionBase
keine weiteren Regeln benötigt.
Wichtige Klassen zur Definition von Regeln
NavigationConfiguration
HauptknotenNavigationGroupControl
NavigationsgruppeExtendedNavigationGroupControl
Erweiterte NavigationsgruppeClientActionBase
Basis aller AktionenDropDownAction
Aufklappelement
Eigenschaften
Den Aktionen kann man Eigenschaften geben, die in der Konfiguration angepasst werden. Beispiel:
[PropertiesGroup("Kundengruppe")] // Übersetzungs GUID verwendbar
[DisplayName("Toastermeldung")] // Übersetzungs GUID verwendbar
[Translate("Training")]
[HelpText("Das ist die Nachricht, die im Toaster ausgegeben wird.")] // Übersetzungs GUID verwendbar
public string Message { get; set; }
Übertragung von Werten an die Type Script Funktion
In der Methode AdditionalRibbonButtonAssignment
können Daten in das AdditionalClientData
Objekt geschrieben werden, welche anschließend in der Type Script Funktion verwendet werden können. Das Beispiel übersetzt den Inhalt einer Eigenschaft in die Sprache des Anwenders und überträgt den Wert.
public override void AdditionalRibbonButtonAssignment(DevExpress.Web.RibbonButtonItem ribbonItem, EnumActionVisibleForParentType parentType, DevExUIModelBase uiModel = null)
{
base.AdditionalRibbonButtonAssignment(ribbonItem, parentType, uiModel);
AdditionalClientData.AddOrUpdate("Message", Api.Text.Format(Message));
}
Der Wert kann nun in der Type Script Funktion verwendet werden.
public static ClientActionMyAction(event: any, customData: CustomData) {
alert(customData.Message as string);
}
Aktiv / Inaktiv der Aktion
Wenn Aktionen in Masken verwendet werden, kann es Situationen geben, in denen die Aktionen nicht ausgeführt werden dürfen. Dazu verwendet man das Objekt DynamicClientVisibility
und fügt diesem bestimmte Verhalten hinzu.
Fehlende Rechte
Falls der Benutzer keine Bearbeitungsrechte auf den aktuellen Datensatz hat, sollen bestimmte Aktionen nicht möglich sein.
Falls dies bei der eigenen Aktion der Fall ist, muss im Konstruktor folgende Zeile hinzugefügt werden:
DynamicClientVisibility.Add(EnumActionVisibility.IfUserHasRole);
Benötigte Client Daten
AdditionalClientData.AddOrUpdate("UserHasRole", true/false);
Des Weiteren muss das Interface IOrmSecurityHandler
implementiert und die Methode CanHandleOrm
überschrieben werden. Mit dem Setzen des Wertes auf true
wird signalisiert, dass der aktuelle Benutzer den Datensatz bearbeiten darf.
public bool CanHandleOrm(object DataObject, OrmBABase orm) { .... }
Beispiel
public bool CanHandleOrm(object DataObject, OrmBABase orm)
{
bool canHandle;
if (orm != null)
canHandle = orm.IsAllowed(EnumTableOperations.Edit);
else
{
OrmEntityConfiguration entityConfig = Api.Config.OrmEntity(EnumDataSourceExtension.MyDataTable.ValueGuid);
canHandle = entityConfig.IsAllowed(EnumTableOperations.Edit) != EnumTableOperations.Denied;
}
AdditionalClientData.AddOrUpdate("UserHasRole", canHandle);
return canHandle;
}
Weitere Möglichkeiten
Die Auswahlliste EnumActionVisibility
beinhaltet eine Reihe weiterer Möglichkeiten. Die prinzipielle Verwendung ist immer identisch. Im Konstruktor wird das Verhalten definiert und die dazu benötigten Daten werden in das AdditionalClientData
Objekt geschrieben. Ein paar Beispiele:
Datensatz muss gespeichert sein
DynamicClientVisibility.Add(EnumActionVisibility.OnlyWhenSaved);
Maskenwert beinhaltet einen definierten Wert
DynamicClientVisibility.Add(EnumActionVisibility.IfFormValueContainsValue);
AdditionalClientData.AddOrUpdate("TestValueContains", "Hallo");
AdditionalClientData.AddOrUpdate("TestFormContains", "Subject");
Maskenwert beinhaltet einen definierten Wert nicht
DynamicClientVisibility.Add(EnumActionVisibility.IfFormValueNotContainsValue);
AdditionalClientData.Add("TestValueNotContains", "Hallo");
AdditionalClientData.Add("TestFormNotContains", "Subject");
Clientside Funktion liefert True zurück
DynamicClientVisibility.Add(EnumActionVisibility.IfMethodReturnsTrue);
AdditionalClientData.AddOrUpdate("IfMethodReturnsTrueMethod", "BA.Customer.Project.Ui.Utils.CheckVisibility");
Sichtbar in Masken und/oder Ansichten
DynamicClientVisibility.Add(EnumActionVisibility.OnlyForFormMode);
DynamicClientVisibility.Add(EnumActionVisibility.OnlyForGridLocation);