Du bist nicht angemeldet.

Stilllegung des Forums
Das Forum wurde am 05.06.2023 nach über 20 Jahren stillgelegt (weitere Informationen und ein kleiner Rückblick).
Registrierungen, Anmeldungen und Postings sind nicht mehr möglich. Öffentliche Inhalte sind weiterhin zugänglich.
Das Team von spieleprogrammierer.de bedankt sich bei der Community für die vielen schönen Jahre.
Wenn du eine deutschsprachige Spieleentwickler-Community suchst, schau doch mal im Discord und auf ZFX vorbei!

Werbeanzeige

Affje

Treue Seele

  • »Affje« ist der Autor dieses Themas

Beiträge: 89

Beruf: Student

  • Private Nachricht senden

1

05.06.2011, 08:49

[C#] Elemente einer Listbox löschen

Hallo,

die Überschrift ist vielleicht etwas verwirrend, da es ja kein großes Hexenwerk ist, aus einer listBox mit

Quellcode

1
listBox.Items.RemoveAt(<index>)

ein Element zu löschen - zumindest in der Theorie.
Ich habe eine Klasse erstellt und Instanzen dieser Klasse werden in der listBoxEvents angezeigt. Ein wechseln der Elemente klappt einwandfrei, doch wenn ich ein Item löschen will, gibt es eine NullReferenceException in der

Quellcode

1
listBoxEvents_SelectedIndexChanged

Methode.

Ziel ist es, im Nachhinein die Instanzen der Klasse zu bearbeiten. Dafür habe ich eine neue Form, in die ich im Konstruktor die Instanz übergebe, ich kann sie dann schön bearbeiten und neu abspeichern, nur eben das Entfernen klappt nicht.

Die Edit-Form:

Quellcode

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
    public partial class Edit : Form
    {

        Main main;
        Daten dataSet;
        int ind;

        //Konstruktor
        public Edit(Daten d, int index, Main incoming)
        {

            InitializeComponent();

            //Aktuelles Datum einstellen
            dateTime.Value = DateTime.Today;

            main = incoming;
            dataSet = d;
            ind = index;
        
            //Werte setzen
            textBoxName.Text = d.name;
            textBoxOrt.Text = d.ort;
        }

        
        //Schließen
        private void buttonClose_Click(object sender, EventArgs e)
        {
            this.Close();
        }


        //Änderungen speichern
        private void buttonSave_Click(object sender, EventArgs e)
        {
            dataSet.name = textBoxName.Text;
            dataSet.ort = textBoxOrt.Text;
            
            //Datum erstellen, ohne Zeit
            String Datum = dateTime.Value.ToString();
            String [] test = Datum.Split(' ');

            //Datum setzen
            dataSet.datum = test[0];
            MessageBox.Show(dataSet.datum);

            //Titel setzen
            dataSet.title = dataSet.datum + " - " + dataSet.name + " - " + dataSet.ort + " (" + dataSet.disziplin + ")";

            main.listBoxEvents.Items.RemoveAt(ind);
            main.listBoxEvents.Items.Add(dataSet);


            this.Close();
        }

    }


Die SelectedIndexChanged-Methode:

Quellcode

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
        //anderes Event wurde ausgewählt
        private void listBoxEvents_SelectedIndexChanged(object sender, EventArgs e)
        {
            summeEvent = 0;
            Daten d = (Daten)listBoxEvents.SelectedItem;
            
            //Durchmesser anpassen
            diameter = d.diameter;

            listBoxShots.Items.Clear();
            
            //Schüsse hinzufügen
            for (int i = 0; i < d.xValues.Length; i++)
            {
                listBoxShots.Items.Add(Convert.ToString(d.rings[i]));
            }

            //Summe ermitteln
            for (int i = 0; i < d.rings.Length; i++)
            {
                summeEvent += d.rings[i];
            }

            labelSumme.Text = "Ringe: " + Convert.ToString(summeEvent) + " / " + d.rings.Length * 10 + " (" + Math.Round((double)summeEvent / (d.rings.Length * 10) * 100, 2) + "%)";
            visualShots(d.xValues, d.yValues);

            //Eventoptionen enabled=true;
            buttonEdit.Enabled = true;
            buttonDelete.Enabled = true;
        }


Wenn ich jetzt allerdings statt dem ausgewählten Index in RemoveAt z.b. ein RemoveAt(0) mache, wird das einwandfrei entfernt. Ziel ist es aber, das alte Event zu löschen und an der alten Position das bearbeitete einzufügen, oder das alte nicht zu löschen, sondern einfach zu "überschreiben".
Ich hoffe, ich habe das einigermaßen verständlich rübergebracht.

MfG Sascha

BlueCobold

Community-Fossil

Beiträge: 10 738

Beruf: Teamleiter Mobile Applikationen & Senior Software Engineer

  • Private Nachricht senden

2

05.06.2011, 09:52

Und wo ist genau das Problem jetzt? Vielleicht solltest Du auch mal den relevanten Code zeigen, der das RemoveAt vornimmt (oder vornehmen soll), damit wir sehen, was Du eigentlich genau vor hast, denn das wird aus dem Kontext irgendwie für mich nicht richtig ersichtlich. Es riecht aber etwas, als ob Du keine Prüfung durchführst, ob das "SelectedItem" eventuell null ist. Denn auch das kann absolut und durchaus vorkommen.

Übrigens finde ich die Benennung Deiner Variablen und Klassen grauenhaft. "Daten" ist so aufschlussreich wie gar kein Name. Und dieses Denglisch ist auch nicht sonderlich förderlich. Im Gegenzug hast Du aber da, wo es wirklich nicht notwendig gewesen wäre, (Code-Smell) Kommentare angebracht.
Teamleiter von Rickety Racquet (ehemals das "Foren-Projekt") und von Marble Theory

Willkommen auf SPPRO, auch dir wird man zu Unity oder zur Unreal-Engine raten, ganz bestimmt.[/Sarkasmus]

Affje

Treue Seele

  • »Affje« ist der Autor dieses Themas

Beiträge: 89

Beruf: Student

  • Private Nachricht senden

3

05.06.2011, 10:59

Und wo ist genau das Problem jetzt? Vielleicht solltest Du auch mal den relevanten Code zeigen, der das RemoveAt vornimmt (oder vornehmen soll), damit wir sehen, was Du eigentlich genau vor hast, denn das wird aus dem Kontext irgendwie für mich nicht richtig ersichtlich. Es riecht aber etwas, als ob Du keine Prüfung durchführst, ob das "SelectedItem" eventuell null ist. Denn auch das kann absolut und durchaus vorkommen.

Übrigens finde ich die Benennung Deiner Variablen und Klassen grauenhaft. "Daten" ist so aufschlussreich wie gar kein Name. Und dieses Denglisch ist auch nicht sonderlich förderlich. Im Gegenzug hast Du aber da, wo es wirklich nicht notwendig gewesen wäre, (Code-Smell) Kommentare angebracht.
Hi,

Zeile 51 und 52.
Und ja, das selektierte "Item" ist null, fraglich ist wieso. Dasselbe "Item" wurde ja in die Forum übergeben und da kann ich es ganz normal verarbeiten, d.h. irgendwie ist es dann eben doch nicht null.
Und zu den Variablen etc. - ich geb mir künftig mehr Mühe ;)

Edit: Wenn ich jetzt in der Main-Form folgendes per OnClick mache:

Quellcode

1
listBoxEvents.Items.Remove((Daten)listBoxEvents.SelectedItem);

dann funktioniert es teilweise einwandfrei und der Eintrag wird wie gewünscht entfernt, manchmal gibt es allerdings wieder die NullReferenceException.

Dieser Beitrag wurde bereits 1 mal editiert, zuletzt von »Affje« (05.06.2011, 11:07)


BlueCobold

Community-Fossil

Beiträge: 10 738

Beruf: Teamleiter Mobile Applikationen & Senior Software Engineer

  • Private Nachricht senden

4

05.06.2011, 11:26

Du weißt schon, dass wenn alle Items abgewählt wurden der SelectedIndex auf -1 und das SelectedItem auf null gesetzt wird?
Teamleiter von Rickety Racquet (ehemals das "Foren-Projekt") und von Marble Theory

Willkommen auf SPPRO, auch dir wird man zu Unity oder zur Unreal-Engine raten, ganz bestimmt.[/Sarkasmus]

Affje

Treue Seele

  • »Affje« ist der Autor dieses Themas

Beiträge: 89

Beruf: Student

  • Private Nachricht senden

5

05.06.2011, 11:47

Du weißt schon, dass wenn alle Items abgewählt wurden der SelectedIndex auf -1 und das SelectedItem auf null gesetzt wird?
Ich klicke in der Liste auf einen Eintrag und entferne ihn mit der Zeile oben (das mit dem OnClick). Wenn ich jetzt das nächste Element löschen möchte, klicke ich wieder darauf und erneut auf den Button usw. Das geht einige Male gut, aber irgendwann kommt die NullReferenceExxception, das versthee ich nicht.
Wenn der Fehler gleich beim ersten Entfernen käme, könnte ich es verstehen, beim zweiten vielleicht auch noch. Aber wieso erst beim 6-7. wenn ich immer gleich vorgehe?

BlueCobold

Community-Fossil

Beiträge: 10 738

Beruf: Teamleiter Mobile Applikationen & Senior Software Engineer

  • Private Nachricht senden

6

05.06.2011, 11:48

Tja, da Du wieder nur den halben Code zeigst, kann Dir das keiner sagen. Allerdings finde ich die Idee mit dem "ind" ganz schlecht, da Du "ind" nie änderst, nachdem Du ein Item gelöscht hast. Gibt es diesen Index also nach dem Löschen nicht mehr, wird beim nächsten Mal ein Fehler auftreten.
Wieso Du da nicht vernünftiger Weise "SelectedIndex" nimmst, das ist mir unklar. Übrigens gibt es da ein gutes Tool um sowas zu finden, es heißt Debugger.
Teamleiter von Rickety Racquet (ehemals das "Foren-Projekt") und von Marble Theory

Willkommen auf SPPRO, auch dir wird man zu Unity oder zur Unreal-Engine raten, ganz bestimmt.[/Sarkasmus]

Affje

Treue Seele

  • »Affje« ist der Autor dieses Themas

Beiträge: 89

Beruf: Student

  • Private Nachricht senden

7

05.06.2011, 12:04

Tja, da Du wieder nur den halben Code zeigst, kann Dir das keiner sagen. Allerdings finde ich die Idee mit dem "ind" ganz schlecht, da Du "ind" nie änderst, nachdem Du ein Item gelöscht hast. Gibt es diesen Index also nach dem Löschen nicht mehr, wird beim nächsten Mal ein Fehler auftreten.
Wieso Du da nicht vernünftiger Weise "SelectedIndex" nimmst, das ist mir unklar. Übrigens gibt es da ein gutes Tool um sowas zu finden, es heißt Debugger.
Auf der Main-Form, also nichts mit ind oder ähnlichem:

Quellcode

1
2
3
4
        private void buttonDelete_Click(object sender, EventArgs e)
        {
                listBoxEvents.Items.RemoveAt(listBoxEvents.SelectedIndex);
        }


--> Sofort Exception

Quellcode

1
2
3
4
        private void buttonDelete_Click(object sender, EventArgs e)
        {
                listBoxEvents.Items.Remove((Daten)listBoxEvents.SelectedItem);
        }

sporadische Exception, mal klappts, mal nicht, mal ziemlich oft, mal gar nicht ;)

Und zum Thema Debugger, da habe ich sofort gesehen, dass das Item null ist, natürlich ists null, sonst käme ja die tolle Meldung nicht. Bringt mir nicht so wirklich viel, da ich nicht weiss, wieso das ganze null ist, wo es doch eigentlich nicht null sein sollte/dürfte :D
Der Exception tritt wie gesagt im

Quellcode

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
        private void listBoxEvents_SelectedIndexChanged(object sender, EventArgs e)
        {
            summeEvent = 0;
            Daten d = (Daten)listBoxEvents.SelectedItem;
            
            //Durchmesser anpassen
            diameter = d.diameter;

            listBoxShots.Items.Clear();
            
            //Schüsse hinzufügen
            for (int i = 0; i < d.xValues.Length; i++)
            {
                listBoxShots.Items.Add(Convert.ToString(d.rings[i]));
            }

            //Summe ermitteln
            for (int i = 0; i < d.rings.Length; i++)
            {
                summeEvent += d.rings[i];
            }

            labelSumme.Text = "Ringe: " + Convert.ToString(summeEvent) + " / " + d.rings.Length * 10 + " (" + Math.Round((double)summeEvent / (d.rings.Length * 10) * 100, 2) + "%)";
            visualShots(d.xValues, d.yValues);

            //Eventoptionen enabled=true;
            buttonEdit.Enabled = true;
            buttonDelete.Enabled = true;
        }

auf, da würde das mit -1 als Index ja irgendwie passen, auch wenn ich jedes mal einen neuen Eintrag auswähle, wo dann der Index = -1 nicht so ganz passt.

BlueCobold

Community-Fossil

Beiträge: 10 738

Beruf: Teamleiter Mobile Applikationen & Senior Software Engineer

  • Private Nachricht senden

8

05.06.2011, 12:07

Der SelectedIndex wird auch geändert und die Changed-Methode aufgerufen, wenn Du ein selektiertes Item löschst, nicht nur wenn Du als Anwender ein Element mit der Maus auswählst.
Nutz überall SelectedIndex, ohne ihn irgendwie zwischenzuspeichern. Und prüfe auf -1, bzw. null. Das löst all Deine Sorgen in einem Schlag.

Die Elemente einer Form Y aus einer Klasse X heraus zu ändern ist übrigens auch eine sehr schlechte Idee.
Teamleiter von Rickety Racquet (ehemals das "Foren-Projekt") und von Marble Theory

Willkommen auf SPPRO, auch dir wird man zu Unity oder zur Unreal-Engine raten, ganz bestimmt.[/Sarkasmus]

Affje

Treue Seele

  • »Affje« ist der Autor dieses Themas

Beiträge: 89

Beruf: Student

  • Private Nachricht senden

9

06.06.2011, 20:11

Der SelectedIndex wird auch geändert und die Changed-Methode aufgerufen, wenn Du ein selektiertes Item löschst, nicht nur wenn Du als Anwender ein Element mit der Maus auswählst.
Nutz überall SelectedIndex, ohne ihn irgendwie zwischenzuspeichern. Und prüfe auf -1, bzw. null. Das löst all Deine Sorgen in einem Schlag.

Die Elemente einer Form Y aus einer Klasse X heraus zu ändern ist übrigens auch eine sehr schlechte Idee.
Hallo nochmal.
Danke dir für die vielen Antworten, es hat wirklich gereicht, die zwei Lösungsvorschläge einzubauen. Ich habe jetzt vor den eigentlichen Code der selectedIndexChanged Methode einfach ein

Quellcode

1
2
3
4
5
6
7
Daten d = (Daten)listBoxEvents.SelectedItem;
if (d != null)
{
.
.
.
}


und zur Sicherheit bei der eigentlichen Löschmethode noch das hier eingefügt:

Quellcode

1
2
3
4
5
6
7
        private void buttonDelete_Click(object sender, EventArgs e)
        {
            if (listBoxEvents.SelectedIndex >= 0 && listBoxEvents.SelectedItem != null)
            {
                listBoxEvents.Items.RemoveAt(listBoxEvents.SelectedIndex);
            }
        }

Jetzt läuft es, so wie ich es angedacht habe und es laufen soll :)

Danke, MfG
Sascha

Werbeanzeige