Entwickler-Ecke

WPF / Silverlight - Checked Listbox


csharpuser1 - Mi 16.11.16 18:10
Titel: Checked Listbox
Guten Tag,
ich habe mir die generische Klasse aus dem Internet geholt um eine checked Listbox zu machen. Wie bekomme ich nun raus, ob ein Element wirklich gecheckt ist oder nicht? Die Klasse Startup.xaml.cs habe ich erstellt und hier konnte ich Elemente meiner Listbox hinzufügen mit einer Checkbox daneben. Wie frage ich nun aber ab, welcher Customer gecheckt wurde?

Klasse Startup.xaml.cs


C#-Quelltext
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:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Shapes;
using System.Collections.ObjectModel;
 
namespace Test_Datei_auswählen
{
    /// <summary>
    /// Interaktionslogik für StartUp.xaml
    /// </summary>
    public partial class StartUp : Window
    {
        public class Customer { public string Name { get; set; } }
 
        public ObservableCollection<CheckedListItem<Customer>> Customers { get; set; }
        public StartUp()
        {
            InitializeComponent();
            Customers = new ObservableCollection<CheckedListItem<Customer>>();
            Customers.Add(new CheckedListItem<Customer>(new Customer() { Name = "Hans" }));
            Customers.Add(new CheckedListItem<Customer>(new Customer() { Name = "Franz" }));
            DataContext = this;            
        }
    }
}


Klasse CheckedList.cs


C#-Quelltext
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:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.ComponentModel;
 
namespace Test_Datei_auswählen
{
    public class CheckedListItem<T> : INotifyPropertyChanged
    {
        public event PropertyChangedEventHandler PropertyChanged;
        private bool isChecked;
        private T item;
        public CheckedListItem() { }
        public CheckedListItem(T item, bool isChecked = false)
        {
            this.item = item;
            this.isChecked = isChecked;
        }
        public T Item
        {
            get { return item; }
            set
            {
                item = value;
                if (PropertyChanged != null) PropertyChanged(thisnew PropertyChangedEventArgs("Item"));
            }
        }
        public bool IsChecked
        {
            get { return isChecked; }
            set
            {
                isChecked = value;
                if (PropertyChanged != null) PropertyChanged(thisnew PropertyChangedEventArgs("IsChecked"));
            }
        }
    }
}


Klasse StartUp.xaml

XML-Daten
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
<Window x:Class="Test_Datei_auswählen.StartUp"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        Title="StartUp" Height="361" Width="463">
 
    <Grid>
        <ListBox ItemsSource="{Binding Customers}" Margin="10,39,141,10" >
            <ListBox.ItemTemplate>
                <DataTemplate>
                    <CheckBox IsChecked="{Binding IsChecked}" Content="{Binding Path=Item.Name}" />
                </DataTemplate>
            </ListBox.ItemTemplate>
        </ListBox>
    </Grid>
</Window>


Moderiert von user profile iconTh69: Topic aus C# - Die Sprache verschoben am Mi 16.11.2016 um 17:46
Moderiert von user profile iconTh69: C#- durch XML-Tags ersetzt


Th69 - Mi 16.11.16 18:55

Hallo,

z.B. mittels Linq:

C#-Quelltext
1:
var checkedCustomers = Customers.Where(item => item.IsChecked).Select(c => c.Item);                    

So erhältst du eine Liste aller 'gecheckten' Customers.


csharpuser1 - Mi 16.11.16 19:04

und dann könnte ich ganz einfach über

if(checkedCustomer[0] == "Hans") ... darauf zugreifen?


Ralf Jansen - Mi 16.11.16 19:38

Nein. Erstmal ist das Ergebnis einer solchen Abfrage nur etwas aufzählbares (ein IEnumerable) . Die Einträge haben keinen Index über den du zugreifen könntest.
Du könntest aber zum Beispiel mit einem foreach über alle Einträge iterieren um dir alle anzusehen.

Wenn du wegen irgendwas auf einen bestimmten Index zugreifen müßtest (das klingt eher ungewöhnlich) mußt du erst was draus machen das einen Indexzugriff erlaubt (eine IList).
Dazu könntest du auf checkedCustomer einfach ToArray oder ToList aufrufen um eine entsprechende Liste zu bekommen.

Moderiert von user profile iconTh69: C#-Tags hinzugefügt


csharpuser1 - Mi 16.11.16 22:14

okay, oder gibt es eine ganz andere Möglichkeit wie ich das angehen kann? Ich habe im Prinzip nur eine Auflistung von 8 Dingen, wo ich möchte, dass der Benutzer diese anklicken oder nicht kann. Meinetwegen klickt er 5 Dinge an und drückt dann auf weiter. Dann müssen mir diese 5 Dinge eine 1 zurückliefern und die anderen drei eine 0. Gibt es vielleicht noch eine klügere Methode dafür?

EDIT: ich könnte natürlich einfach einen Textblock nehmen und daneben immer passend eine Checkbox, das ist aber sehr unschön oder?

Grüße


Delete - Mi 16.11.16 22:27

- Nachträglich durch die Entwickler-Ecke gelöscht -


csharpuser1 - Mi 16.11.16 23:21

Gibt es nicht wie bei den guten alten Windows Forms eine Methode a la


C#-Quelltext
1:
2:
3:
4:
5:
if(checkBox1.CheckState == CheckState.Checked)
{
  Array[0] = 1
}
else array[0] = 0;


Dann könnte ich ganz einfach alle Checkboxen machen und zack den State aller Checkboxen bei Button Klick an das Array geben und anschließend damit weiterarbeiten.

mit WPF bin ich noch nicht warm geworden..

habe es immer noch nicht hinbekommen :(


Delete - Do 17.11.16 01:50

- Nachträglich durch die Entwickler-Ecke gelöscht -


Th69 - Do 17.11.16 10:02

Hallo csharpuser1,

Ralf hat es doch geschrieben: einfach ToList oder ToArray aufrufen.

C#-Quelltext
1:
2:
3:
4:
5:
var checkedCustomers = Customers.Where(item => item.IsChecked).Select(c => c.Item);

List<Customer> customers = checkedCustomers.ToList();
// oder
Customer[] customers = checkedCustomers.ToArray();

Auch dein für WinForms geschriebener Code ist außerdem nicht sinnvoll (viel zu umständlich - C&P-Code ist generell zu vermeiden).

Wenn du statt der Liste (bzw. Array) direkt auf die Einträge per Index zugreifen willst, dann ruf einfach

C#-Quelltext
1:
Customers[0].IsChecked // bzw. .Item                    

auf deinem Originalcode auf.

Vllt. solltest du mal näher beschreiben, was du mit den gecheckten Items genau anfangen willst.