C# ListBoxen mit Objekten

Firestorm-

Lt. Commander
Registriert
Okt. 2006
Beiträge
2.015
Tag zusammen,

ich versuche mich mal als Java-Folllower an C#. Konkret geht es um Folgendes:

Ich bau gerade eine Form die eine ListBox enthält. Die Methodensignatur der Methode .Add() verrät mir, dass ich alles mögliche als Element in eine ListBox schreiben kann, da sie ein object erwartet. Wenn ich genau dies tue, also sprich ein Objekt reinzuschreiben, beispielsweise ein Panel Objekt, dann bekomm ich schlichtweg nichts angezeigt ausser den Namespace des Objekts.

Ich weiss aber dass es geht.. Strings alleine reichen mir nicht.. Ich brauch ein Panel, welches weitere Controls enthält die zur Laufzeit mir Daten gefüttert werden im Sinne einer passive View.

Hoffe ihr könnt mir einen Tipp geben...

Anbei die relevante Zeile des Quellcodes, der mein Vorhaben untermauert:

Code:
// then this might be a candidate for the resultlist
                        view.listBox.Height += 13;
                        view.listBox.Items.Add(new ListBoxItem(item.Key, tempFileName, item.Value));


und noch die Klasse ListBoxItem:

Code:
public partial class ListBoxItem : UserControl
    {

        private Icon image;
        private string filename;
        private string path;

        public ListBoxItem(Icon in_image, string in_filename, string in_path)
        {
            this.image = in_image;
            this.filename = in_filename;
            this.path = in_path;

            InitializeComponent();

            SetTheImageIcon();
            SetTheFileName();
            SetThePath();
        }

Kennt ihr eine Lösung für mein Problem?

Greets, Fire
 
Hi,

in einer normalen C# Listbox kannst du zwar alle Objekte reinschieben, was angezeigt wird ist immer der String der bei der Methode *.ToString() zurückgeliefert wird, mehr nicht.

D.h. wenn du bei deinem Objekt die ToString() überlädst, kannst du den Text bestimmen der da steht. Mehr kann das Ding halt nicht.

Grüße,

d2boxSteve
 
Zuletzt bearbeitet: (Tippfehler ...)
Es muss irgendeine eine Möglichkeit geben...

@endless90: Das ist leider eine ListView... Ich seh da aber dasselbe Problem momentan... Hm.
 
wie schon oben gesagt, wird der ToString von dem Objekt angezeigt. Was aber im Item übergeben wird ist dein Object aus der Liste. Das heißt dass du jeden Object den du aus deine ListBox gewählt hast einzel ansprechen kannst. Einfach den Debugger aufdrehen und beim event SelectedItem sehen was zurückgeliefert wird! Ich würde aber aufpassen mit dem add während der Laufzeit, da es hier ab und zu Probleme geben kann. BindingList wäre hier die Passenden Lösung!
 
Ich versteh zwar nicht ganz warum du da das ListBoxItem überschreibst, und auf was genau du mit deiner Frage abzielst, aber wenn du spezielle Properties einer Klasse anzeigen willst die du in als Objekt in die Listbox reingibst, dann könnte dir vielleicht die Property

Code:
Listbox.DisplayMemberPath = "DeinePropertyDieAngezeigtwerdenSoll";

helfen.
Wenn ich das falsch verstanden habe, bitte klär mich doch etwas näher auf.
 
Die ListBox wird dynamisch zur Laufzeit mit Einträgen befüllt. Davor wird davor das "zeichnen" unterbrochen und nach dem hinzufügen wieder fortgesetzt. Das Problem ist dass ich nicht von vorne rein eine Property binden oder eine Collection als DataSource an die Liste binden kann da diese ja erst zu Laufzeit erstellt wird.
Es geht also in die Richtung einer IntelliSense-Funktionalität.

Ich glaub ich werds einfach nochmal mit der ListView versuchen.. Vielleicht lässt diese sich so umbiegen dass ich optisch und semantisch das gleiche Ergebnis erreiche wie ich es mir ursprünglich mit einer ListBox vorgestellt habe.

Ich werd euch dann berichten sobald ichs hinbekommen habe (was ich zumindest hoffe)...

@rooker:
Klar dass am Object nur 5 oder 6 Methoden dranhängen. Es geht mir auch nicht um das SelectedItem, denn das wird definitv als Object zurückgeliefert, sofern es nicht vorher schon implizit konvertiert wird.
Mich würde interessieren welche Probleme du beim Befüllen der ListBox zur Laufzeit siehst?

@toeffi:
Ziel ist es eine ListBox mit Einträgen zu befüllen die selbst ein Panel sind und in sich selbst weitere Controls wie Labels, Pictures, etc.. enthalten. Meine Annahme war, dadurch dass die Methode Add() ein Object erwartet, dass das oben beschriebene Ziel einfacher umsetzbar ist, da ich ein Object reinpacken kann.
 
Add macht nichts anderes als einen Object an die interne Liste dran zu hängen. Es ist glaube ich egal ob es die gleiche Objekte sind oder nicht. Wenn du überschreiben willst versuchs mit Items.Insert(int, Object)

Was ich mit Problemen gemeint habe beim einfügen bzw. entfernen von Objekten in der Liste ist, dass du jedes mal die Liste "unterbrechen" musst, wie du vorhin schon geschrieben hast. Mit dem BindingList hast du das Problem nicht. Die Liste synchronisiert sich automatisch mit dem DataSource des ListItems und verursacht keine Probleme beim bearbeiten.
 
Also ich weiß ja nicht ob du Winforms oder WPF machst, aber ich kann dir WPF nur ans Herz legen dort kannst du genannte Probleme total einfach mit einem Template für deine Listbox lösen.
 
@toeffi: Okay.. Ich werds mir mal anschauen.. Kombinieren lassen sich WinForms und WPF aber nicht oder?

Ich mein ich bin bisher Swing und AWT gewöhnt... :)
 
Okay damit ihr seht wie ich mir das vorstelle hab ich einen kleinen Screenshot gemacht, der ursprünglich aus der aktuellen Skype-Version stammt. Der Aufbau soll prinzipiell der gleiche sein, bis auf das Statussymbol, das brauch ich nicht.

Unbenannt.png


Es bleibt mir wohl oder Übel nur der Weg über eine Collection die an die ListBox/View gebunden wird.
Dann brauch ich irgendeinen schlauen Cache-Algo der die Listenelemente möglichst effizient verwaltet..
Problem ist aber nach wie vor das Layout...
 
Zuletzt bearbeitet:
Was heißt wohl oder Übel, das ist der Standardwerdegang in WPF/WinForms. Schließlich kümmern sich ja die Controls darum das die Elemente angezeigt werden.
Und die Layoutproblematik ist auch kein Hit mit WPF, wie gesagt schau es dir mal an.
 
Hab mal das Ganze ein wenig hier verfolgt. Ich denke ich würde deine "Aufgabe" über ein System.Windows.Forms.TableLayoutPanel lösen. Dabei würde ich den ColumnCount auf 1, GrowStyle auf AddRow, Marging und Padding auf 0 setzen. Danach kannst du beliebig viele UserControls, Controls zu dem TableLayoutPanel hinzufügen und diese werden dann der Reihe nach untereinander gesetzt. Sollten mehr Controls als verfügbarer Platz hinzugefügt werden, dann gibts automatisch einen Scrollbalken.

Insgesamt wäre das dann über die altmodischen Windows Forms realisiert, vielleicht weiß toeffi ob es was vergleichbares im WPF gibt ...
 
Naja es geht eigentlich nur darum in einer Listbox die Items benutzerdefiniert anzuzeigen und genau das ist ja die Spezialität von WPF.
Dort machst du nichts weiter als ein Template zu erstellen(DataTemplate) und dieses DataTemplate wendest du als ItemTemplate an der Listbox an.
Jetzt musst du nur noch eine Klasse bauen die genau deinen Listboxeintrag darstellt und die Properties der Klasse bindest du an dein DataTemplate.
Jetzt brauchst du nur noch eine Collection der Items die in die Listbox sollen und diese bindest du als ItemSource an die Listbox.
Ich habe dazu mal was auf meinem Blog rausgesucht, lass dich von der Komplexität des Beispiels nicht abschrecken das ist schon etwas fortgeschrittenere WPF aber das ist ja im Endeffekt das was du haben willst.
http://www.blog-dotnetprogrammierung.de/?p=214
Dort siehst du ja das folgende XAML:
Code:
<DataTemplate x:Key="PersonListItemTemplate">
        <DataTemplate.Resources>
            <local:StatusToImageConverter x:Key="StatusToImageConverter"/>
        </DataTemplate.Resources>
        <StackPanel Orientation="Horizontal">
            <Image Source="{Binding IsOnline,Converter={StaticResource StatusToImageConverter}}" Stretch="None" Margin="5"/>
            <TextBlock Text="{Binding FirstName}" Margin="2" FontWeight="Bold"/>
            <TextBlock Text="{Binding LastName}" Margin="2" FontWeight="Bold"/>
        </StackPanel>
    </DataTemplate>
Diese DataTemplate repräsentiert genau einen Eintrag in der Listbox und du siehst wie ich die Listbox individuell designed habe.

Ich hoffe ich konnte soweit helfen,ansonsten fragen.
 
@Rossibaer:

Der Gedanke kam mir auch schon.. Hab die Umsetzung aber ein wenig vor mich hin geschoben weil es eigentlich nicht so vorgesehen war.. Ich werd es aber auf jeden Fall im Hinterkopf behalten.


@toeffi:

Danke ich werd es mal so probieren!
 
Halt dich am besten an das was toeffi geschrieben hat. Mit WPF und einem oben genannten DataTemplate kannst du quasi alles anstellen, ohne krude UserControls mixen zu müssen.

Prinzip von WPF ist es durch das deutlich verbesserte Data Binding quasi jegliches object unabhängig von seiner Komplexität in der UI abbilden zu können.

Problem daran ist nur, dass die Lernkurve ziemlich steil ist, die ersten Wochen quält man sich da durch, aber dann ist man nur noch froh ;)
 
Zurück
Oben