Sortieren von eigenen Objekttypen in einem DataGridView

20/04/2009 - 16:44 von Andreas | Report spam
Hallo,

ich habe in einer WinForm-App eine Liste mit eigenen Typen.
(List<MyType>)
Diese wird mittels BindingSource an eine GridView gebunden. Nun sollen
die Eintràge über die Header sortiert werden können. Leider
funktioniert hierbei gar nichts. Weder Events noch irgendetwas anderes
wird ausgelöst oder gar sortiert.

Wie kann man dies realisieren? In meine Klasse habe ich schon mit
IComparable implementiert. Dies wird aber nur auf das gesamte Objekt
angewendet. Ich möchte eine Sortierung für die angezeigten Attribute
haben.

Danke,
Andreas
 

Lesen sie die antworten

#1 Frank Dzaebel
20/04/2009 - 19:36 | Warnen spam
Hallo Andreas,

ich habe in einer WinForm-App eine Liste mit eigenen Typen.
(List<MyType>) Diese wird mittels BindingSource an
eine GridView gebunden. Nun sollen die Eintràge über die
Header sortiert werden können. Leider funktioniert hierbei
gar nichts.



ja, das alte Problem. List<T> ist eben doch recht "flach"
und stellt keine Bindungs-Unterstützung zur Verfügung.
Da sind DataTable, DataView, oder allgemeiner
IBindingList mit SupportsSorting eben geeigneter.

Nun, da Du ~wohl wenig Aufwand haben möchtest,
ist es zum Beispiel möglich, Deine "List<MyType>"
in "SortingList<MyType>" umzuwandeln, die intern
den DefaultComparer des Type's benutzt.
Ein Beispiel:

public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}

SortingList<Person> list = new SortingList<Person>();
DataGridView dgv = new DataGridView();
BindingSource bs;

private void Form1_Load(object sender, EventArgs e)
{
for (int i = 0; i < 20; i++)
list.Add(new Person(i, "Vorname" + i,
"Nachname" + i));
Controls.Add(dgv);
bs = new BindingSource(list, "");
dgv.DataSource = bs;
dgv.Dock = DockStyle.Fill;
this.Width = 400;
}

class Person
{
public Person(int alter, string vorname, string nachname)
{
Alter = alter;
Vorname = vorname;
Nachname = nachname;
}

public int Alter { get; set; }
public string Vorname { get; set; }
public string Nachname { get; set; }
}

public class SortingList<T> : BindingList<T>
{
private bool isSorted = false;
private ListSortDirection sortDir;
private PropertyDescriptor sortProp;

protected override bool SupportsSortingCore
{
get { return true; }
}

protected override bool IsSortedCore
{
get { return isSorted;}
}

protected override ListSortDirection SortDirectionCore
{
get { return sortDir; }
}

protected override PropertyDescriptor SortPropertyCore
{
get { return sortProp; }
}

public void AddRange(IEnumerable<T> collection)
{
IEnumerator<T> e = collection.GetEnumerator();
while (e.MoveNext()) this.Add(e.Current);
}

public T Find(Predicate<T> match)
{
List<T> items = this.Items as List<T>;
if (items != null) return items.Find(match);
else return default(T);
}

public int FindIndex(Predicate<T> match)
{
List<T> items = this.Items as List<T>;
if (items != null) return items.FindIndex(match);
else return -1;
}

public bool Exists(Predicate<T> match)
{
List<T> items = this.Items as List<T>;
return items.Exists(match);
}

public void Sort()
{
List<T> items = this.Items as List<T>;
if (items != null) items.Sort();
}

public void Sort(Comparison<T> comparison)
{
List<T> items = this.Items as List<T>;
if (items != null) items.Sort(comparison);
}

public void Sort(IComparer<T> comparer)
{
List<T> items = this.Items as List<T>;
if (items != null) items.Sort(comparer);
}

protected override void ApplySortCore(
PropertyDescriptor prop, ListSortDirection direction)
{
sortProp = prop; sortDir = direction;
List<T> items = this.Items as List<T>;
if (items != null)
{
PropertyComparer<T> pc = new
PropertyComparer<T>(prop, direction);
items.Sort(pc); isSorted = true;
}
else isSorted = false;

OnListChanged(new ListChangedEventArgs(
ListChangedType.Reset, -1));
}

protected override void RemoveSortCore()
{
isSorted = false;
}
}

public class PropertyComparer<T> : IComparer<T>
{
private ListSortDirection sortDir;
private PropertyDescriptor prop;
public PropertyComparer(PropertyDescriptor
property, ListSortDirection direction)
{
prop = property; sortDir = direction;
}

public int Compare(T x, T y)
{
int compVal = Comparer.Default.Compare(
prop.GetValue(x), prop.GetValue(y));
if (sortDir == ListSortDirection.Descending)
compVal = -compVal;
return compVal;
}
}
}
___________________________________

Dennoch gibt es auch andere Ansàtze, die
meine oben angesprochenen Bindungs-Möglichkeiten
von DataTable etc. nutzen:

[Converting Custom Collections To and From DataTable]
http://blog.lozanotek.com/archive/2...Table.aspx

Oder gleich von Anfang an DataTable o.à. benutzen,
(natürlich nur, wenn es in die Architektur/Anforderungen passt)


ciao Frank
Dipl.Inf. Frank Dzaebel [MCP/MVP C#]
http://Dzaebel.NET

Ähnliche fragen