Eine Mehrfachgruppierung zeigt einen Datensatz mehrfach an. Beispielsweise abhängig davon wie viele Auswahlwerte gewählt worden sind.

Das Steuerelement wird wie vorher implementiert, nur für das Drag & Drop wird anstatt IGridDataColumnControl das Interface IGridGroupingColumnControl implementiert.

Der Renderer implementiert IGridColumnMultiGroupControlRenderer welches das Interface IGridColumnControlRenderer erweitert. Im Folgenden werden nur die Unterschiede zu den vorherigen Renderern beschrieben.

Definition der Joins

Für die Definition der Joins muss die Methode GetJoins implementiert werden. In dem Beispiel werden zwei Joins definiert. Der Erste joined die Relationstabelle und beschränkt diese auf eine bestimmte Relation. Die Zweite joined den Datensatz der die Quelle der Relation ist.

Wird eine Ansicht mehrfach gruppiert, muss sichergestellt sein, das die Row Id eindeutig ist. Wenn dies nicht der Fall ist, ist die Ansicht in einem undefinierten Zustand und es können dann beispielsweise leere Zeilen erscheinen. In einer nicht mehrfachgruppierten Ansicht entspricht die Row Id der Oid des dargestellten Datensatzes. Bei einer mehrfachgruppierten Ansicht ist die Oid nicht mehr eindeutig. Daher muss beim Join angegeben werden ob die Oid des Join Queries als Teil der Row Id verwendet werden soll.
In dem Beispiel wird die Oid der Relation als Row Id genutzt RowIdPart = true. Diese ist in diesem Fall dann eindeutig.

public IEnumerable<GridViewQueryJoinProperties> GetJoins(GridColumnBase column)
{
    return new[]
    {
        new GridViewQueryJoinProperties
        {
            // Eindeutiger Name des Joins
            Name = "RelationJoin",
            // Der .Net Typ der Orm Klasse
            EntityType = typeof(OrmRelation),
            // Eigenschaft des übergeordneten Queries als Key für diesen Join
            MainKey = nameof(OrmBABase.Oid),
            // Eigenschaft des Join Queries als Key für diesen Join
            Key = nameof(OrmRelation.Target),
            // Bedingung zur Einschränkung der Menge in Formel
            Where = CriteriaOperatorBuilder.GetRelationJoinCondition(true, false, relationType, relationCategory),
            // Flag ob die Oid des Join Queries in die Row Id mit aufgenommen werden soll.
            RowIdPart = true,
        },
        new GridViewQueryJoinProperties
        {
            Name = "SourceJoin",
            EntityType = Api.ORM.GetOrmTypeCacheValue(dataSourceGuid),
            MainKey = nameof(OrmRelation.Source),
            Key = nameof(OrmBABase.Oid),
        }
    };
}

Datenbankabfrage

Soll die Formel für eine Eigenschaft in GetQueryProperties auf den Datensatzverweisen, welcher über die Joins hinzugebunden ist, muss in den GridViewQueryColumnProperties die Eigenschaft UseMultiGroupJoins auf true gesetzt werden.

Zusätzlicher Filter

In der Regel möchte man, dass Datensätze, die keine Werte haben auch nicht in der Ansicht auftauchen, um leere Kategorien zu vermeiden. Dazu kann man in GetFilterExpression eine Filter-Formel definieren, die den anderen Filtern hinzugefügt wird. Filter-Formeln müssen einen booleschen Wert zurückliefern.

public virtual CriteriaOperator GetFilterExpression(GridColumnBase column)
{
    return CriteriaOperatorBuilder.GetSourcesJoin(false, EnumRelationType.Author, EnumAuthorRelationSubTypes.Default, onlyRelations: true, aggregator: Aggregate.Exists);
}