Benutzer mit den meisten Antworten
ListCollectionView mit generischem Filter

Frage
-
Hallo NG,
ich verwende derzeit folgende Zeilen um in einer ListviewCollection zu filtern
this.GeneralDataView = new ListCollectionView(objList); this.GeneralDataView.Filter = item => DataTextFilter(item as CarDealerShip); ... private bool DataTextFilter(CarDealerShip pRowItem) { string textFilterString = (this.SearchFilter ?? string.Empty).ToUpper(); string[] words = textFilterString.Split(new[] { ' ' }, StringSplitOptions.RemoveEmptyEntries); foreach (string word in words) { //Autohaus, Strasse, // PLZ, Ort, Anrede, Ansprechpartner, //Telefon, Email, ManReportPos, HaendlerGruppe bool wordFound = (pRowItem.Autohaus != null && pRowItem.Autohaus.ToUpper().Contains(textFilterString)); if (!wordFound) { return false; } } return (true); }
Nun ist es immer etwas mühselig von der übergebenen Klasse immer alle Properties zu schreiben, die ausgewertet werden sollen. Gibt es eine generische Möglichkeit dazu ?
Gruß
Gerhard Ahrens
Antworten
-
Natürlich ist das ganze über Reflection möglich, ich würde es aber eher meiden. Denn erstens denke ich, das die Zugriffe länger dauern und 2. Entsteht ein Tippfehler in einem String viel schneller als im richtigen Quelltext. Dort würde sich ggf. der Compiler melden.
Wenn du trotz meiner bedenken so etwas realisieren willst, dann hast du hier ein ungetesteten Ansatz:
class Program { static void Main(string[] args) { MyClass mc = new MyClass();//Klasse instanzieren (zum testen) mc.CheckValues(//Test-Werte übergeben new CompareObject() { Name = "Property1", Value = "String", IgnoreCaseByStrings = false }, new CompareObject() { Name = "Property2", Value = 12, IgnoreCaseByStrings = false }, new CompareObject() { Name = "Property3", Value = 15.8M, IgnoreCaseByStrings = false }, new CompareObject() { Name = "Property4", Value = MeinObjekt, IgnoreCaseByStrings = false }, new CompareObject() { Name = "Property5", Value = "ABC123", IgnoreCaseByStrings = true }); } } static class Extensions { public static bool CheckValues(this object obj, params CompareObject[] names) { foreach (CompareObject name in names)//Alle Vergleiche durch gehen { var prop = obj.GetType().GetProperty(name.Name);//Eigenschaft laden var val = prop.GetValue(obj, null);//Wert laden if (prop.PropertyType == typeof(string) && name.IgnoreCaseByStrings)//String ohne Groß-/Kleinschreibung vergleichen { if (val.ToString().ToLower() != name.Value.ToString().ToLower()) return false; } else if (val != name.Value)//Objekte vergleichen return false; } return true;//Alle Werte ok } } //Für den Vergleich. zusätzlich noch ein paar Parameter für den Vergleich angeben struct CompareObject { public string Name { get; set; }//Name der Eigenschaft public object Value { get; set; }//Value public bool IgnoreCaseByStrings { get; set; }//Sonstige Eigenschaften etc. }
Aber hier machst du dir wahrscheinlich nur mehr Arbeit, zumal obiger Aufruf von CheckValues länger wäre als der klassische Vergleich.
Koopakiller [kuːpakɪllɐ] (Tom Lambert)
Webseite |
Code Beispiele |
Facebook |
Twitter |
Snippets
C# ↔ VB.NET Konverter
Markiert bitte beantwortende Posts als Antwort und bewertet Beiträge. Danke.- Bearbeitet Tom Lambert (Koopakiller)Moderator Freitag, 13. Dezember 2013 19:27 Code kommentiert/korrigiert
- Als Antwort markiert Gerhard Ahrens Montag, 16. Dezember 2013 06:21
Alle Antworten
-
Hallo,
ich verstehe nicht so ganz, was du vor hast. Meinst du diese Abfrage hier?(pRowItem.Autohaus != null && pRowItem.Autohaus.ToUpper().Contains(textFilterString))
Natürlich kann es aufwendig werden alles eintippen zu müssen, aber woher soll denn eine Methode wissen, was du wann, wo und wie vergleichen willst?
Generika hat mit dem ganzen auch nur bedingt etwas zu tun. Eventuell ist es möglich eine Erweiterunbgsmethode o.ä. zu schreiben die häufig verwendetes zusammen fasst, aber mehr ist da auch nicht möglich.
Koopakiller [kuːpakɪllɐ] (Tom Lambert)
Webseite |
Code Beispiele |
Facebook |
Twitter |
Snippets
C# ↔ VB.NET Konverter
Markiert bitte beantwortende Posts als Antwort und bewertet Beiträge. Danke. -
Hallo Tom,
ja, genau den Teil meine ich. Ich dache an Reflection und an eine Liste von Feldern. So eine Konstrukt mit mehr als 5 Properties sieht einfach doof aus. Hmm eine Erweiterungmethode mit einer Liste von Feldern die so ein Ergebnis bringt wäre natürlich auch hilfreich.
bool ok = (pRowItem.Prop1 != null && pRowItem.Prop1.ToUpper().Contains(textFilterString)) ||
(pRowItem.Prop2 != null && pRowItem.Prop2.ToUpper().Contains(textFilterString)) ||
....
Ist einfach schwierig zu handhaben. Vor allem wenn dann noch weitere Datetypen dazu kommen
die immer erst nach String konvertiert werden müssen.
Danke und Gruß
Gerhard Ahrens -
Natürlich ist das ganze über Reflection möglich, ich würde es aber eher meiden. Denn erstens denke ich, das die Zugriffe länger dauern und 2. Entsteht ein Tippfehler in einem String viel schneller als im richtigen Quelltext. Dort würde sich ggf. der Compiler melden.
Wenn du trotz meiner bedenken so etwas realisieren willst, dann hast du hier ein ungetesteten Ansatz:
class Program { static void Main(string[] args) { MyClass mc = new MyClass();//Klasse instanzieren (zum testen) mc.CheckValues(//Test-Werte übergeben new CompareObject() { Name = "Property1", Value = "String", IgnoreCaseByStrings = false }, new CompareObject() { Name = "Property2", Value = 12, IgnoreCaseByStrings = false }, new CompareObject() { Name = "Property3", Value = 15.8M, IgnoreCaseByStrings = false }, new CompareObject() { Name = "Property4", Value = MeinObjekt, IgnoreCaseByStrings = false }, new CompareObject() { Name = "Property5", Value = "ABC123", IgnoreCaseByStrings = true }); } } static class Extensions { public static bool CheckValues(this object obj, params CompareObject[] names) { foreach (CompareObject name in names)//Alle Vergleiche durch gehen { var prop = obj.GetType().GetProperty(name.Name);//Eigenschaft laden var val = prop.GetValue(obj, null);//Wert laden if (prop.PropertyType == typeof(string) && name.IgnoreCaseByStrings)//String ohne Groß-/Kleinschreibung vergleichen { if (val.ToString().ToLower() != name.Value.ToString().ToLower()) return false; } else if (val != name.Value)//Objekte vergleichen return false; } return true;//Alle Werte ok } } //Für den Vergleich. zusätzlich noch ein paar Parameter für den Vergleich angeben struct CompareObject { public string Name { get; set; }//Name der Eigenschaft public object Value { get; set; }//Value public bool IgnoreCaseByStrings { get; set; }//Sonstige Eigenschaften etc. }
Aber hier machst du dir wahrscheinlich nur mehr Arbeit, zumal obiger Aufruf von CheckValues länger wäre als der klassische Vergleich.
Koopakiller [kuːpakɪllɐ] (Tom Lambert)
Webseite |
Code Beispiele |
Facebook |
Twitter |
Snippets
C# ↔ VB.NET Konverter
Markiert bitte beantwortende Posts als Antwort und bewertet Beiträge. Danke.- Bearbeitet Tom Lambert (Koopakiller)Moderator Freitag, 13. Dezember 2013 19:27 Code kommentiert/korrigiert
- Als Antwort markiert Gerhard Ahrens Montag, 16. Dezember 2013 06:21