![]() |
Container-Klassen in C#
Ich will Objekte einer Klasse in einer Liste, Container-Klasse verwalten. Wie es mit Delphi funktioniert, weiß ich:
![]() ![]() |
Re: Container-Klassen in C#
List<T>?
|
Re: Container-Klassen in C#
Oh Gott, was ist denn das jetzt für ein Konstrukt? Ich habe mit C# so gut wie keine Erfahrung. Ich bitte dies zu berücksichtigen, wenn ihr mir Hilfe in Form von Stcihworten anbietet. Mit
Code:
kann ich nämlich irgendwie nichts so recht anfangen.
List<T>
|
Re: Container-Klassen in C#
Verzeihung. Ich war gar nicht sicher, was du genau suchst.
System.Collections.Generic.List<T> (Visual Studio fügt normalerweise automatisch in neuen Dateien ein "using System.Collections.Generic" ein) ist ein generischer Listentyp (also Template-Klasse, je nachdem, welche Bezeichnung du dafür eher kennst). Wenn du also zum Beispiel Control-Ableitungen verwalten kennst, kannst du dafür ein List<Control> nehmen. Die Templateklassen findest du normalerweise in der Hilfe auch mit T als Typangabe, also einfach mal "List<T>" eingeben. Edit: Der Name trügt übrigens. List ist keine verkettete Liste. Allgemein kannst du dich auch mal in "Collection" einlesen, und in die in diesem Zusammenhang interessanten Interfaces IEnumerable, das u.a. von List<T> und auch normalen Arrays implementiert wird. |
Re: Container-Klassen in C#
Und weil wir uns hier in der DP befinden, vorsorglich noch den Hinweis, dass es generische Klassen, also alles mit <T>, erst ab NET 2.0 gibt. Aber grundsätzlich ist List<T> in der Tat optimal für Listen von speziellen Objekten geeignet.
Gruß Jürgen |
Re: Container-Klassen in C#
Ja, stimmt, Luckie, mit welcher C#-Version entwickelst du denn? Das spielt da natürlich schon eine Rolle :)
|
Re: Container-Klassen in C#
Mit dem VC2008 Beta und dem Framework 3.5.
|
Re: Container-Klassen in C#
In dem Fall sind unter Umständen auch die neuen Containerklassen für dich interessant. Die Namen weiß ich nicht so genau. Aber im Zusammenhang mit WPF stößt du da schnell drauf. Die haben standardisierte Interfaces für Änderungsbenachrichtigungen und so Zeugs.
|
Re: Container-Klassen in C#
Ich glaube, ich habe da schon was. Ich poste das dann mal, wenn ich hier fertig bin.
|
Re: Container-Klassen in C#
Zitat:
Am interessantesten wäre da INotifyPropertyChanged in den Datenklassen zu implementieren und als Liste eine BindingList<T> zu nehmen. Dadurch können die Datenklassen durch die Liste der UI bescheid sagen, wenn sich eine Eigenschaft geändert hat, die BindingList selbst ist außerdem in der Lage, die UI darüber zu informieren, dass Elemente hinzugefügt/entfernt/geändert wurden. |
Re: Container-Klassen in C#
Ich verstehe nur noch Bahnhof. :gruebel:
Jedenfalls habe ich es jetzt mal so gemacht:
Code:
Ist da irgendein schwerwiegender Fehler drin?
namespace Container_Klasse
{ public partial class Form1 : Form { List<Person> PersonenListe = new List<Person>(); private void UpdateControls() { toolStripStatusLabel1.Text = PersonenListe.Count.ToString(); lbEntries.Items.Clear(); foreach (Person person in PersonenListe) { lbEntries.Items.Add(person.Name + ", " + person.Vorname); } tbName.Text = string.Empty; tbVorname.Text = string.Empty; btnDel.Enabled = (PersonenListe.Count > 0) && (lbEntries.SelectedIndex > -1); } public Form1() { InitializeComponent(); UpdateControls(); } private void btnAdd_Click(object sender, EventArgs e) { Person p = new Person(tbName.Text, tbVorname.Text); PersonenListe.Add(p); tbName.Focus(); UpdateControls(); } private void lbEntries_SelectedIndexChanged(object sender, EventArgs e) { btnDel.Enabled = lbEntries.SelectedIndex > -1; if (lbEntries.SelectedIndex > -1) { tbName.Text = PersonenListe[lbEntries.SelectedIndex].Name; tbVorname.Text = PersonenListe[lbEntries.SelectedIndex].Vorname; } } private void btnDel_Click(object sender, EventArgs e) { if (lbEntries.SelectedIndex > -1) { PersonenListe.RemoveAt(lbEntries.SelectedIndex); UpdateControls(); } } } } Wie könnte ich das ganze jetzt noch nach Name und Vorname sortieren? Habs:
Code:
private static int ComparePerson(Person p1, Person p2)
{ if (p1.Name == p2.Name) return p1.Vorname.CompareTo(p2.Vorname); else return p1.Name.CompareTo(p2.Name); } private void UpdateControls() { toolStripStatusLabel1.Text = PersonenListe.Count.ToString(); PersonenListe.Sort(ComparePerson); lbEntries.Items.Clear(); foreach (Person person in PersonenListe) { lbEntries.Items.Add(person.Name + ", " + person.Vorname); } tbName.Text = string.Empty; tbVorname.Text = string.Empty; btnDel.Enabled = (PersonenListe.Count > 0) && (lbEntries.SelectedIndex > -1); } |
Re: Container-Klassen in C#
Zitat:
Kompilere einmal dein Projekt, gehe jetzt mal in den Form designer und oben im Menü klickst du auf du Data\Show data sources. Nun legst du in dem neuen Toolwindow eine neue Data source an, im Dialog wählst du Object aus und im nächsten Schritt kannst du deine Klasse "Person" auswählen -> Finish. Jetzt kannst du einfach die Eigenschaften Name und Vorname auf dein Formular. Die Textboxes sind jetzt an diese beiden Eigenschaften in der PersonBindingSource gebunden, die ebenfalls auf dem Form liegt. Willst du den Navigator nicht haben, kannst du ihn einfach löschen. Jetzt noch eine ListBox auf dein Form ziehen, und ihr als DataSource die personBindingSource verpassen. Mehr muss im Form nicht stehen, um all das zu können, was dein Code gemacht hat:
Code:
public partial class Form1 : Form
{ readonly BindingList<Person> persons = new BindingList<Person>(); public Form1() { InitializeComponent(); personBindingSource.DataSource = persons; } private void personBindingSource_ListChanged(object sender, ListChangedEventArgs e) { deleteButton.Enabled = personBindingSource.Position != -1; nameTextBox.Enabled = deleteButton.Enabled; vornameTextBox.Enabled = deleteButton.Enabled; } private void addButton_Click(object sender, EventArgs e) { personBindingSource.AddNew(); } private void deleteButton_Click(object sender, EventArgs e) { personBindingSource.RemoveCurrent(); } } In der Klasse würd ich halt INotifyPropertyChange implementieren, um die UI (oder andere) über Änderungen informieren zu können. Außerdem habe ich noch ToString überschrieben, da das der Defaultwert ist, den eine ListBox darstellt.
Code:
public class Person : INotifyPropertyChanged
{ string name; string vorname; public override string ToString() { return name + ", " + vorname; } public string Name { get { return name; } set { if (name == value) return; name = value; RaisePropertyChanged("Name"); } } public string Vorname { get { return vorname; } set { if (vorname == value) return; vorname = value; RaisePropertyChanged("Name"); } } public event PropertyChangedEventHandler PropertyChanged; protected void RaisePropertyChanged(string propertyName) { PropertyChangedEventHandler h = PropertyChanged; if (h != null) h(this, new PropertyChangedEventArgs(propertyName)); } } |
Re: Container-Klassen in C#
Hallo,
Zitat:
Grüße Mephisto |
Re: Container-Klassen in C#
Zitat:
Es ist die generische Vorsetzung der Arraylist. LinkedList<T> ist eine verkette Liste. |
Re: Container-Klassen in C#
Zitat:
Zitat:
|
Re: Container-Klassen in C#
Zitat:
Zitat:
|
Re: Container-Klassen in C#
@elvis: Das ist sicher auch eine Möglichkeit, aber ich wollte ja wissen, wie es von Hand geht, um es zu verstehen. Letztendlich will ich mich etwas in C# einarbeiten, um zu sehen, wie es funktioniert usw.
Zum Vergleichen habe ich jetzt mal eine Klasse implementiert:
Code:
class PersonComparer: IComparer<Person>
{ public enum SortType {Descending = -1, Ascending = 1}; protected SortType sortType; public PersonComparer() { this.sortType = SortType.Ascending; } public PersonComparer(SortType st) { this.sortType = st; } public SortType HowToSort { set{this.sortType = value;} } public int Compare(Person p1, Person p2) { if (p1.Name == p2.Name) return (int)sortType * p1.Vorname.CompareTo(p2.Vorname); else return (int)sortType * p1.Name.CompareTo(p2.Name); } } |
Re: Container-Klassen in C#
Hallo,
Zitat:
Grüße Mep |
Re: Container-Klassen in C#
Zitat:
Wie diese Bindung dann aussieht, kannst du mit einigen Interfaces selbst bestimmen. Zitat:
Code:
var sortType = SortType.Blabla;
personenListe.Sort((left, right) -> (int)sortType * (left.Name != right.Name) ? String.Compare(left.Name, right.Name) : String.Compare(left.Vorname, right.Vorname)); |
Alle Zeitangaben in WEZ +1. Es ist jetzt 21:27 Uhr. |
Powered by vBulletin® Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024-2025 by Thomas Breitkreuz