Hallo zusammen,
ich hoffe das ich hier richtig bin.
Also erst einmal etwas Vorgeschichte:
Ich brauche ein DataGrid bei dem die letzten beiden Zeilen nicht bei der Sortierung berücksichtigt werden. So ein DataGrid hab ich auch gefunden
C#/WPF Toolkit: DataGrid - Footer Row / summary row
Jetzt hab ich mir das runter geladen und bei mir eingbaut und soweit so gut funktioniert das auch, aber nur unter folgenden bedingungen. Das Element das Sortiert werden soll muss einen publich setter und getter haben, also beim Binding muss TwoWay möglich sein und die Spalte die existiert muss so wie sie gebunden wird auch in dem Objekt das die Zeilen beschreibt vorhanden sein.
Beispiel:
public class Person
{
public string Name { get; set; }
public string Hobby1 { get; set; }
public string Hobby2 { get; set; }
public string Hobby3 { get; set; }
public string Hobby4 { get; set; }
public string Hobby5 { get; set; }
}
Dieser Aufbau funktioniert.
Jetzt möchte ich aber das es eine Variable anzahl an Hobbys möglich ist also habe ich folgendes gebaut.
public class Person
{
public string Name { get; set; }
public List<string> Hobbies { get; set; }
}
Jetzt kann ich mir dynamisch DataGridColumns aufbauen die sich dann an die Einzelnen Elemente Binden die in Hobbies stehen und gut ist.
Leider nicht ..... denn der PropertyAccessor der verwendet wird
(Hier zu finden: Fast Dynamic Property Access with C#)
bekommt den PropertyNamen als String übergeben und jetzt wir versucht mit der GetPropertyMethode(string propertyName) zum Beispiel das Property "Hobbies[0]" in der Person zu finden.
Das ist aber so nicht vorhanden und wird natürlich nicht gefunden und es wird eine Exception geworfen und da sind wir auch schon bei meinem Problem.
Ich weiß nicht wie ich das hinbekommen soll das er das Element 0 der liste abfragt und nicht versuch "Hobbies[0]" als eigenes Property zu interpretieren.
Zusätzlich sollte noch zu sagen sein das natürlich Properties die nicht in einer Liste stehen auch noch sortierbar bleiben müssen.
Ich hoffe ihr versteht was ich brauche und wo mein Problem ist und das jemand hilfe für mich hat.
Gruß Dijon
Hallo Dijon
Deinem gefundenen "Control" konnte ich entnehmen das es sich wohl um WPF handelt.
Ich brauche ein DataGrid bei dem die letzten beiden Zeilen nicht bei der Sortierung berücksichtigt werden. So ein DataGrid hab ich auch gefunden
Du kannst doch einfach das default Grid benutzen und sowas machen :
var sortedData = myData.OrderBy(d=>d.Hallo).ThenBy(d=>d.Welt);
sortedData.Add(myLastItem1);
sotedData.Add(myLastItem2);
myGrid.ItemSource=sortedData;
Beste Grüsse
Diräkt
Edit :
Ich kenne Dein Control nicht, wenn du dieses aber verwenden willst, könntest ja mal folgendes testen:
Hobbies[0] sieht nach einem Array aus, kannst ja versuchen Deine Liste als Array zu deklarieren 😃
Oder du kannst auch sowas versuchen
public string this[this key]
get { return dictionary[key]; }
set { dictionary[key] = value; }
Hallo Diräkt , danke für deine rasche Meldung.
Dein erste Lösungsvorschlag würde heißen das ich jedesmal wenn ich sortiere müsste ich die letzten beiden Zeilen abschneiden, speichern, dann sortieren und danach die zeilen wieder anfügen. Den Aufwand würde ich mir gerne ersparen deswegen habe ich mir ja dies Lösung die ich gepostet habe gesucht und genutzt ich muss es im endeffekt nur List fähig machen.
Der Zweite ansatz hieße das ich das Personen-Objekt von einer Liste ableiten müsste um dann halt
this[] nutzen zu können aber das ist ja auch nicht mein Ziel.
Mein DataGrid Control ist genau so aufgebaut wie es in dem obrigen Beispiel beschrieben ist , es ist auch das DataGrid aus dem WPFToolkit.
Gruß Dijon
Hallo Dijon
Den Aufwand würde ich mir gerne ersparen
Ja gerade schön ist es nicht, das stimmt, obwohl Aufwand ist übertrieben, das ist ein 3-4 Zeiler.
Wenn ich mir Deine Struktur anschaue :
public class Person
{
public string Name { get; set; }
public List<string> Hobbies { get; set; }
}
Ist das für mich :
Main Table:
Name
Detail Table:
Hobbies
Daher würde ich das auch so anzeigen, oder ich versteh wirklich nicht was du meinst. Ist dein Ziel:
Hans Schwimmen Super gut
Hans Rennen Nicht sehr gut
Reto Laufen Perfekt
Reto Schlafen Schlecht
Oder was genau willst du erreichen ?
Beste Grüsse
Diräkt
Oder was genau willst du erreichen ?
So wie ich es verstanden habe, wird nach dem ersten Eintrag vom Hobbies-Property sortiert, die anderen Einträge werden ignoriert:
jetzt wir versucht mit der GetPropertyMethode(string propertyName) zum Beispiel das Property "Hobbies[0]" in der Person zu finden.
Dann wäre evtl. folgende Struktur ganz praktisch:
public class Person
{
public string Name { get; set; }
private List<string> Hobbies { get; set; }
public string Hobby
{
get { return Hobbies.Count == 0 ? string.Empty : Hobbies[0];
}
}
Dann kann man nach dem Hobby-Property sortieren lassen.
Christian
Weeks of programming can save you hours of planning
Hallo Dijon,
die Methode PropertyInfo.GetValue hat einen extra Parameter für den Index-Wert. Du kannst also Hobbies[0] nicht einfach als ersten Parameter übergeben, sondern müsstest es vorher aufteilen und Hobbies als ersten und 0 (verpackt in einem Object-Array) als zweiten Parameter verwenden.
Wenn du die Klasse PropertyAccessor verwendest, müsstest du sie so anpassen, dass sie die Aufteilung vornimmt und dann entsprechenden Code für einen Indexzugriff emittiert.
herbivore
Hallo zusammen,
vielen dank für eure vielen Zuschriften und ich merke das ich euch noch ein paar Details schuldig bin.
Das Anzeigen der Daten soll in der View nachher so aussehen.
Hobby[0] Hobby[1] Hobby[2]
Personname Fahrradfahren Laufen Schwimmen
Hans sehr gerne ungerne manchmal
Klaus ungerne sehr gerne sehr gerne
in der letzten Zeile soll dann eine Art auswertung gemacht werden. In etwa so
Auswertung Es wird gerne Es wird gerne Es wird häufig
Fahrrad gefahren gelaufen geschwommen
Das ist der Plan hinter dem ganzen und es soll natürlich die letzte Zeile nicht verschoben werden
wenn ich nun eine Column Sortiere. Sonst würde die Zeile mit der Auswertung irgendwo stehen
wenn ich nun nach, zum Beispeil, Hobby[1] sortiere.
Ich bekomme an folgenden Stellen probleme:
Im Konstrucktor des PropertyAccessors
public PropertyAccessor(Type targetType, string property)
{
this.mTargetType = targetType;
this.mProperty = property;
PropertyInfo propertyInfo = targetType.GetProperty(property);
//
// Make sure the property exists
//
if(propertyInfo == null)
{
throw new PropertyAccessorException(
string.Format("Property \"{0}\" does not exist for type "
+ "{1}.", property, targetType));
}
else
{
this.mCanRead = propertyInfo.CanRead;
this.mCanWrite = propertyInfo.CanWrite;
this.mPropertyType = propertyInfo.PropertyType;
}
}
In der Zeile
PropertyInfo propertyInfo = targetType.GetProperty(property);
hab ich das erste Problem denn dort findet er natürlich nicht "Hobbies[1]" also habe ich versuch das "[0]" abzuschneiden damit der nur nach "Hobbies" schaut und das geht auch.
wenn ich das aber an dieser Stelle mache und in diesem Konstrucktor sage hau mir die "[0]" weg dann kommt es an einer anderen Stelle zum Problem.
Und zwar hier im Konstrucktor vom PropertyComparer
public PropertyComparer(string propertyName, ListSortDirection direction)
{
accessor = new PropertyAccessor(typeof(T), propertyName);
var comparerForPropertyType =
typeof(Comparer<>).MakeGenericType(typeof(T).GetProperty(propertyName).PropertyType);
comparer =
(IComparer)
comparerForPropertyType.InvokeMember("Default",
BindingFlags.Static | BindingFlags.GetProperty |
BindingFlags.Public, null, null, null);
SetListSortDirection(direction);
}
In dieser Zeile wird dann eine NullReferenceException geworfen wenn propertyName "Hobbies[0]" ist.
var comparerForPropertyType =
typeof(Comparer<>).MakeGenericType(typeof(T).GetProperty(propertyName).PropertyType);
Wenn ich also hingehe und noch vor dem PropertyComparer die "[0]" müsstes es gehen aber dann bekomme ich hier eine Ausnahme.
public int Compare(T x, T y)
{
return reverse * comparer.Compare(accessor.Get(x), accessor.Get(y));
}
Das ist dann eine ArgumentException mit dem Hinweis: > Fehlermeldung:
Mindestens ein Objekt muss IComparable implementieren.
(Was die Nachricht bedeutet weiß ich, ich weiß nur noch wo ich den IComparable einbinden soll)
Wenn ich jetzt im Debugger weiter gehe dann komme ich zu folgendem Punkt.
Sort(0, countToSort, comparerLast);
Das ist in der Footlist die von List erbt und dort wird eine:
InvalidOperationException geworfen mit der Aussage
Fehler beim Vergleichen von zwei Elementen im Array
So das ist alles was ich dazu sagen kann weil mehr bekomme ich vom Debugger nicht.
Gruß Dijon
Naja das ist doch schon recht eindeutig. 🙂
Mach deine Hobby-Objekt vergleichbar (IComparable implementieren) und bau eine Eigenschaft ein, welches die Zusammenfassungszeile kennzeichnet (sofern ich das richtig interpretiert habe, dass die Zusammenfassung auch ein Hobby-Objekt ist)
Wenn Hobby.IsSummary -> beim vergleichen immer nach ganz unten sortieren.
Hobby ist einfach nur ein string und da steht nicht direkt das Hobby drin sonder nur wie gerne das hobby gemacht wir
wie gesagt im Person Objekt existert nur
List<string> Hobbies;
Für mich ist halt die Frage wie das DataGrid das grundsätlich löst mit dem Sortieren denn
ihm ist es ja völlig wumpe ob da jetzt ein Element eines Arrays drin steht oder ob es
ein Attribut ist.
Hallo Dijon,
Für mich ist halt die Frage wie das DataGrid das grundsätlich löst mit dem Sortieren
eben über den IComparer. Lies mal alles gesagte noch mal durch. Du solltest jetzt alle Informationen haben, die du brauchst ...
... vorausgesetzt du beherrschst die Grundlagen, die wir voraussetzen, siehe [Hinweis] Wie poste ich richtig? Punkt 1.1.1 und nutzt die Dokumentation, siehe Punkt 1.1.
herbivore