Falls kein Datenprovider vorhanden ist, der die Auswahl bietet, kann man einen eigenen Datenprovider implementieren. Dafür sind zwei Klassen notwendig, zum einen der Datenprovider selbst und zum anderen seine Eigenschaften.

Eigenschaften des Datenproviders

Die Eigenschaften

  • Die Klasse muss die Basis Klasse ControlDataProviderPropertiesBase erweitern.
  • Die Eigenschaften sollten prinzipiell simple Datentypen sein. Komplexe Datentypen sollten dringend vermieden werden.
    Beispielsweise sollte die Guid einer Konfiguration, anstatt die Konfiguration selbst, definiert werden.
  • Sinnvoll ist es mit Guid, GuidSet, etc. zu arbeiten, auch wenn diese nicht in den Attributen angeben werden können. Die Umwandlung, sollte dann direkt im Konstruktor erfolgen.
  • WICHTIG: Der vollständige Klassenname des eigentlichen Datenproviders muss in die Eigenschaft DataProviderTypeFullName gesetzt werden.

Beispiel

public class CDPEnumValuesProperties : ControlDataProviderPropertiesBase
{
    public Guid MasterGuid { get; set; }
    public bool DisplayIcon { get; set; } = true;
    public EnumEntryActiveState ActiveState { get; set; }
    public GuidSet WantedValues { get; set; }

    public CDPEnumValuesProperties(string masterGuid = null, bool displayIcon = true, string activeState = null, string[] wantedValues = null) : base()
    {
        DataProviderTypeFullName = typeof(CDPEnumValues).FullName;

        if (!string.IsNullOrEmpty(masterGuid))
            MasterGuid = masterGuid.ToGuid();

        DisplayIcon = displayIcon;

        if (activeState != null || activeState.IsGuid())
            ActiveState = Api.Enum.GetEnumValue<EnumEntryActiveState>(activeState.ToGuid());

        WantedValues = GuidSet.Parse(wantedValues);
    }
}

Der Datenprovider

  • Er muss das Interface IControlDataProvider implementieren.
  • In Properties stehen die Eigenschaften zur Verfügung.
  • Die Methode GetRows() liefert das Ergebnis zurück.
    • Es ist sinnvoll Datenprovider so zu implementieren, dass diese selbst erweitert werden können. In diesem Beispiel wurde eine virtuelle Methode AddWhere() implementiert. Diese kann überschrieben werden, und dadurch können weitere Filter implementiert werden.
    • Die Parameter enthalten den Filter, der in der UI vom Anwender eingegeben wurde. Dieser Filter muss auf die Ergebnisliste angewendet werden. In diesem Beispiel in der Methode AddFilter().
  • Die Methode GetByKey() liefert genau ein Ergebnis oder null zurück. Diese sollte nicht unbedingt GetRows() aufrufen, auch wenn dies ohne Probleme möglich ist. Falls es einen effektiveren Weg gibt, sollte dieser gewählt werden.
public class CDPEnumValues : IControlDataProvider
{
    public ControlDataProviderPropertiesBase Properties { get; set; }

    public virtual IQueryable<ControlDataRow> GetRows(ControlDataProviderParameter parameter = null)
    {
        if (Properties != null && Properties is CDPEnumValuesProperties prop)
        {
            IEnumerable<ValueEnum> enumValues = AddWhere(Api.Enum.GetEnumValues(prop.MasterGuid));

            IEnumerable<ControlDataRow> values = enumValues.Select(ff => new ControlDataRow
            {
                Key = ff.GuidString,
                Title = ff.Translation_Guid.ToString().Translate(),
                DataItem = ff,
            });

            if (parameter != null && !string.IsNullOrWhiteSpace(parameter.Filter))
                values = AddFilter(values, parameter.Filter);

            return values.AsQueryable();
        }

        if (Properties == null)
            throw new ArgumentNullException("Data provider: The properties are NULL");

        throw new ArgumentException(String.Format("Data provider: The properties are {0} and not {1}", Properties.GetType().FullName, typeof(CDPEnumValuesProperties).FullName));
    }

    public virtual ControlDataRow GetByKey(string key)
    {
        if (key != null && key.IsGuid())
        {
            ValueEnum value = Api.Enum.GetEnumValue(key.ToGuid());
            if (value != null)
                return new ControlDataRow
                {
                    Key = value.GuidString,
                    Title = value.Translation_Guid.ToString().Translate(),
                    DataItem = value,
                };
        }

        return null;
    }

    public virtual IEnumerable<ValueEnum> AddWhere(IEnumerable<ValueEnum> list)
    {
        if (Properties is CDPEnumValuesProperties prop)
        {
            return list.Where(ff => prop.WantedValues != null && prop.WantedValues.Contains(ff.ValueGuid) && (prop.ActiveState == null || prop.ActiveState == EnumEntryActiveState.All || ff.IsActive == (prop.ActiveState == EnumEntryActiveState.Active)));
        }

        return list;
    }

    public virtual IEnumerable<ControlDataRow> AddFilter(IEnumerable<ControlDataRow> list, string filter)
    {
        string conditionFilterPart = filter.Replace("\"", "").ToLower();
        return list.Where(ff => ff.Title != null && ff.Title.ToLower().Contains(conditionFilterPart));
    }
}