Skocz do zawartości

[Filtr sferyczny] Lista wyboru, z własnymi opcjami, z własnymi warunkami


Zobacz rozwiązanie Rozwiązane przez Mateusz Matuszewski,

Polecane posty

Chciałbym dodać filtr sferyczny na bazie testowej, który będzie się nazywać "Pachnące" dla obiektu Asortyment, miał dwie opcję: "Tak", "Nie". Wybranie jednej z nich, spowoduje odpowiednie odfiltrowanie listy, gdzie jedna z komórek, odpowiednio zawiera różne składowe nazw produktu - nie jest to jeden do jeden, czyli: "dezodorant", "perfum", wszystko będą pod wyborem "Tak". Wychodzę z założenia, że funkcja DodajFiltrListyWyboru, jest odpowiednia, ale w przykładach akurat nie ma informacji, jak manualnie stworzyć Sobie kolekcję WartoscDoWyboru. No i tyle z teorii, z praktyką niestety gorzej, przykłady tego nie obejmują, szczerze przyznaje, że nie wiem, moja znajomość C# tego nie obejmuje, więc będę wdzięczny za nakierowanie.

 

Pierwszy problem, to stworzenie kolekcji, która opiera się o interfejs abstrakcyjny. Dostaje błędem CS0144, więc mam skopaną jej deklarację, ale nie mogę znaleźć przyczyny dlaczego, i czy w ogóle, mogę ją zadeklarować. Dodatkowo, nie mogę też określać identyfikatorów, a zakładam, że mogły by się potem w zapytaniu przydać.

// czy tak
WartoscDoWyboru[] opcje = new WartoscDoWyboru[]
{
   new WartoscDoWyboru { Identyfikator = "bf06c73c-bcc8-447a-80f8-ba365b3a3ba7", Opis = "Tak" },
   new WartoscDoWyboru { Identyfikator = "ba088d29-6279-4b93-8496-faf7402149b2", Opis = "Nie" }
};
// czy też tak, potem do AsEnumerable
var opcje = new List<WartoscDoWyboru> { };
var tak = new WartoscDoWyboru();

Drugi problem, nawet jak powyższe zadziała, to jeszcze kolekcję muszę skonwertować na typ System.Func i tutaj też poległem

rozszerzenie.DodajFiltrListyWyboru<Asortyment, Guid>("Pachnący", opcje, v => a => a.Id == 100000);

 

Link to postu
  • Rozwiązanie

Obecne metody są przeznaczone do tworzenia podstawowych filtrów, a metoda DodajFiltrListyWyboru w założeniu ma przyjmować listę identyfikatorów, które zostaną użyte w wyrażeniu Contains. Tworzenie bardziej zaawansowanych filtrów, w których można by było definiować zachowanie pojedynczych opcji mamy zaplanowane na kolejne wersje. Jednak jak Pan słusznie zauważył, w tym przypadku można zrobić pewne obejście z wykorzystaniem powyższej metody. Nie jest to może najładniejsze rozwiązanie, ale powinno zadziałać :)

Spójrzmy na początku na sygnaturę tej metody. Oczekuje ona podania w parametrach dwóch delegatów: Func<IEnumerable<WartoscDoWyboru<Guid>>> oraz Func<Guid[], Expression<Func<Asortyment, bool>>>. Zatem rozwiązaniem pierwszego problemu jest stworzenie listy obiektów typu WartoscDoWyboru<Guid> i nadanie im odpowiednich guidów w polu Wartosc. Rozwiązaniem drugiego problemu jest po prostu stworzenie delegata zwracającego powyższą listę opcji. Ostatni parametr metody odpowiada za wygenerowanie wyrażenia filtrującego na podstawie opcji wybranych w filtrze. Jeśli wyłączymy multiselekcję, to zawsze wybrana będzie tylko jedna wartość, więc będziemy mogli posłużyć się wtedy prostymi ifami.
 

WartoscDoWyboru<Guid>[] opcje = new WartoscDoWyboru<Guid>[]
{
    new WartoscDoWyboru<Guid> { Wartosc = new Guid("bf06c73c-bcc8-447a-80f8-ba365b3a3ba7"), Opis = "Tak" },
    new WartoscDoWyboru<Guid> { Wartosc = new Guid("ba088d29-6279-4b93-8496-faf7402149b2"), Opis = "Nie" }
};

var definicjaFiltra = rozszerzenie.DodajFiltrListyWyboru<Asortyment, Guid>(
    "Pachnący",
    () => opcje,
    v =>
    {
        if (v[0] == opcje[0].Wartosc) // wybraną opcją jest "Tak"
        {
            return a => a.Nazwa.Contains("dezodorant") || a.Nazwa.Contains("perfum");
        }
        else // wybraną opcją jest "Nie"
        {
            return a => !(a.Nazwa.Contains("dezodorant") || a.Nazwa.Contains("perfum"));
        }
    });
definicjaFiltra.WielokrotnyWyborDostepny = false; // wyłączamy multiselekcję

 

Edytowane przez Mateusz Matuszewski
Literówka, poprawka przykładu
  • Lubię to 1
Link to postu

Dziękuje za pomoc i cenną lekcję!

Zamieszczam lekko zmodyfikowaną wersję, gdzie po wyborze funkcji odnosimy się poprzez case, do konkretnych wartości GUID, to może komuś innemu pomoże ;)

 

        public RozszerzenieListyDanych RozszerzListeDanych(IKontekstListyDanych kontekst)
        {
            var rozszerzenie = new RozszerzenieListyDanych();

            if (kontekst.CzyTypDanychJestPrezentowany(typeof(Asortyment)))
            {
                // lista wartości filtra
                WartoscDoWyboru<Guid>[] opcje = new WartoscDoWyboru<Guid>[]
                {
                new WartoscDoWyboru<Guid> { Wartosc = new Guid("bf06c73c-bcc8-447a-80f8-ba365b3a3ba7"), Opis = "Tak" },
                new WartoscDoWyboru<Guid> { Wartosc = new Guid("ba088d29-6279-4b93-8496-faf7402149b2"), Opis = "Nie" }
                };
                var definicjaFiltra = rozszerzenie.DodajFiltrListyWyboru<Asortyment, Guid>("Pachnący", () => opcje, v =>
                {
                    switch (v[0])
                    {
                        // sprawdzamy wybraną wartość, jeśli nie pasuje żadna, to zwracamy null
                        case var r when (r == new Guid("bf06c73c-bcc8-447a-80f8-ba365b3a3ba7")): return a => a.Nazwa.Contains("dezodorant") || a.Nazwa.Contains("perfum") || a.Nazwa.Contains("woda toaletowa");
                        case var r when (r == new Guid("ba088d29-6279-4b93-8496-faf7402149b2")): return a => !(a.Nazwa.Contains("dezodorant") || a.Nazwa.Contains("perfum") || a.Nazwa.Contains("woda toaletowa"));
                        default: return null;
                    }
                });
                definicjaFiltra.WielokrotnyWyborDostepny = false; // wyłączamy multiselekcję, ale wybór będzie zwrócony jako lista, więc odnosimy się do [0]
            }
            return rozszerzenie;
        }

 

  • Lubię to 1
Link to postu

To jeszcze kilka pytań odnośnie filtrów:

- czy mogę je dodać do informatorów, np. Informator Asortymentu, zakładka Sprzedaż, chciałbym dodać Sobie filtr Kategoria - tak wiem, mogę skorzystać z kolumny, ale to czysto hipotetyczny przykład

- w raportach wbudowanych w NEXO, czasem klienci pytają o dodatkowe filtry (chociaż najczęściej im brakuje pojedyńczych pól, ale to inna para kaloszy, pewnie nie osiągalna).

- w raportach własnych SQL, tak wiem, tam filtry powstają już w zapytaniu, ale pamiętam, że miałem sytuacje, działając na bardziej skomplikowanych zapytaniach, może wtedy takim filtrem coś bym Sobie mógł dobudować, chociaż to takie łatane rozwiązanie, i lepiej to zrobić w całym raporcie sferycznym, ale spytać nie zaszkodzi ;)

Edytowane przez Radomił Ząbik
Link to postu

W raportach wbudowanych i informatorach sprawa jest trochę bardziej skomplikowana, więc aktualnie własne filtry pojawiają się tylko w niektórych z nich. Ostatecznie chcemy, aby filtry dało się dodawać do każdego wbudowanego raportu/informatora, ale nie jestem w stanie powiedzieć kiedy pojawi się taka możliwość.

Co do raportów własnych - aktualnie nie planujemy.

  • Dziękuję 1
Link to postu
  • 1 miesiąc temu...
×
×
  • Dodaj nową pozycję...