Seite 1 von 1

[C#] ListView mit Checkboxes, ItemChecked-Event

Verfasst: 05.04.2012, 15:51
von BeRsErKeR
Hallo ich habe ein ListView, dessen Einträge eine CheckBox enthalten.

Es gibt 2 Buttons um entweder alle Items anzuhaken oder bei allen Items den Haken zu entfernen. Dabei wird über alle Items iteriert und item.Checked entsprechend auf true oder false gesetzt.

Darüber hinaus kann der Nutzer natürlich jedes Item manuell per Klick aktivieren bzw. deaktivieren.


Aus bestimmten Gründen muss ich nun bei jedem dieser Events prüfen ob alle Items, keine Items oder nur manche Items selektiert werden (egal welche, nur diese 3 Zustände).

Bei den beiden Buttons kann ich den Zustand ganz einfach setzen. Bei CheckAll setze ich den Zustand auf AlleMarkiert, bei UncheckAll entsprechend auf KeineMarkiert.

Wenn ich nun aber den Zustand auch nach einem manuellen Klick abfangen will wirds schwieriger. Ich habe dafür das Ereignis ItemChecked abgefangen und prüfe darin eben jenen Zustand (alle, keine oder manche markiert).

Soweit so gut. Das Problem ist nun aber, dass dieses Ereignis auch dann auftritt, wenn ich dem Checked-Wert eines Items einen Wert zuweise, was ich bei den Button-Events tue. Dadurch entspricht das alles nicht mehr dem gewünschten Verhalten.

Meine Idee wäre nun mit einem Flag zu arbeiten, aber das ist recht unschön, zumal das auch gefährlich ist, wenn weitere Events hinzukommen, die Items in der Liste markieren. Dann muss man immer an das Flag denken. Kann man das irgendwie elegant lösen?

Nochmal zum Verständnis. Ich brauche eine Art Event, die nur bei manuellem Häkchensetzen (oder -entfernen) eines Items auftritt, nicht jedoch bei der Zuweisung der Checked-Eigenschaft eines Items im Code. Oder aber einen anderen Lösungsansatz.

Re: [C#] ListView mit Checkboxes, ItemChecked-Event

Verfasst: 05.04.2012, 21:48
von LaBerg
Ich habe mal auf die schnelle was runtergeschrieben, was denke ich deine Anforderungen erfüllen sollte. Bevor ich lange Erklärungen schreibe, poste ich einfach den Quellcode. Ist denke ich verständlicher:

Code: Alles auswählen

 public enum CheckState
        {
            None = 0,
            Some = 1,
            All =2
        }

public CheckState GetCheckState()
        {
            CheckState eCheckState = CheckState.None;
            if (m_oListView.Items.Count == m_oListView.CheckedItems.Count)
            {
                eCheckState = CheckState.All;
            }
            else if (m_oListView.CheckedItems.Count > 0)
            {
                eCheckState = CheckState.Some;
            }
            return eCheckState;
        }

       

        private void OnListViewItemChecked(object sender, ItemCheckedEventArgs e)
        {
            switch (GetCheckState())
            {
                case CheckState.None:
                    m_oTextBox.Text = "Keines";
                    break;
                case CheckState.All:
                    m_oTextBox.Text = "Alle";
                    break;
                case CheckState.Some:
                    m_oTextBox.Text = "Einige";
                    break;
                default:
                    break;
            }
        }

Re: [C#] ListView mit Checkboxes, ItemChecked-Event

Verfasst: 08.04.2012, 19:02
von BeRsErKeR
Danke für die Antwort. Leider löst das nicht mein Problem. Deinen Code habe ich in ähnlicher Form ja bereits. Mein Problem ist aber, dass ich zusätzlich noch 2 Button-Click-Events habe, die allen Items der Liste einen Wert für die Checked-Eigenschaft zuweist und dadurch das Check-Event immer aufgerufen wird. Dadurch funktioniert das ganze System nicht mehr.

Re: [C#] ListView mit Checkboxes, ItemChecked-Event

Verfasst: 09.04.2012, 11:45
von LaBerg
Also ich habe jetzt mal zwei Buttons mit folgenden Event-Handlern hinzugebaut:

Code: Alles auswählen

private void OnCheckAllButtonClick(object sender, EventArgs e)
        {
            foreach (ListViewItem oItem in m_oListView.Items)
            {
                oItem.Checked = true;
            }
        }

private void OnDeselectAllButtonClick(object sender, EventArgs e)
        {
            foreach (ListViewItem oItem in m_oListView.Items)
            {
                oItem.Checked = false;
            }
        }
Das ist doch das was deine beiden Buttons machen, oder?
Das funktioniert bei meinem Code wunderbar, dass da immer der richtige Status in der TextBox angezeigt wird.
Oder ich versteh nicht, was du genau machen willst.

Re: [C#] ListView mit Checkboxes, ItemChecked-Event

Verfasst: 10.04.2012, 16:43
von BeRsErKeR
Danke erstmal. Ich hab leider erst morgen wieder Zugriff auf den Code. Dann schau ich nochmal genau nach.

Re: [C#] ListView mit Checkboxes, ItemChecked-Event

Verfasst: 11.04.2012, 13:47
von BeRsErKeR
So ich konnte es nun testen. Das Problem lag leider an einer anderen Stelle. Ich war wiedermal zu vorschnell. Trotzdem danke für die Hilfe.

Zur Info: Auf Grundlage des berechneten Zustamds (All, None, Some) habe ich bei einem bestimmten Ereignis (bei dem die Liste neu befüllt wird) die neuen Werte wieder alle selektiert oder deselektiert (bei All ersteres, bei Some und None letzteres). Dabei wurde aber wieder das SelectionChanged-Event ausgelöst und hat dann natürlich wieder den Zustand überschrieben. Daher war die Lösung einfach eine temporäre Variable, die sich für den Zeitraum des Selektierens der neuen Einträge den Zustand merkt. ;)

Re: [C#] ListView mit Checkboxes, ItemChecked-Event

Verfasst: 11.04.2012, 14:26
von odenter
Es gibt nur den Status checked oder unchecked. Wenn Dich also alle interessieren die gechecked sind mache Dir eine zweite Liste in die alle Indizes kommen wo gechecked sind.
Ändert sich der checked status passt Du deine Liste an.

Dich interessiert dann nur noch die Liste, dann weisst Du ob alle (count liste != count listbox.items) oder nur bestimmte an/aus sind.
Dann kannste auch ganz ohne Probleme das Event abonieren, und auf der Listbox arbeiten und alles funktioniert. :)

Wobei es grundsätzlich andersherum natürlich besser wäre, Du solltest eine Liste von Stati haben und die Listbox zeigt diese Liste nur an. Drücken der Knöpfe ändert dann die Liste und nicht die Listbox-Items etc.