Laden...

Listbox - Itemtemplate mit Checkboxen (Silverlight)

Erstellt von Xeres vor 13 Jahren Letzter Beitrag vor 13 Jahren 2.950 Views
X
Xeres Themenstarter:in
16 Beiträge seit 2003
vor 13 Jahren
Listbox - Itemtemplate mit Checkboxen (Silverlight)

Hallo,

für ein aktuelles Projekt benötige ich eine Listbox mit einem Itemtemplate, in dem lediglich eine Checkbox enthalten ist.
Sobald der User auf eine Checkbox klickt, möchte ich, dass das entsprechende Item in die Listbox.SelectedItems-Collection geschrieben wird.

Das funktioniert auch soweit. Hier der Zwischenstand meiner derzeitigen Lösung:


<DataTemplate x:Key="templateItem">
    <Grid>
        <CheckBox Name="chkDummy" Content="{Binding Property1}" Checked="chkDummy_Checked" Unchecked="chkDummy_Checked"/>
    </Grid>            
</DataTemplate>

<ListBox Width="150" Height="200" ItemTemplate="{StaticResource templateItem}" ItemsSource="{Binding Collection, Source={StaticResource SampleDataSource}}"
	SelectionChanged="ListBox_SelectionChanged" SelectionMode="Multiple" x:Name="listbox" />

Hier noch der Source-Code der chkDummy_Checked-Routine:

private void chkDummy_Checked(object sender, RoutedEventArgs e)
        {            
            Expression.Blend.SampleData.SampleDataSource.Item checkedItem = (((CheckBox)sender).DataContext as Expression.Blend.SampleData.SampleDataSource.Item);
            if (((CheckBox)sender).IsChecked == true)
            {
                this.listbox.SelectedItems.Add(checkedItem);
            }
            else
            {
                this.listbox.SelectedItems.Remove(checkedItem);
            }
        }

Nun hat der User allerdings auch die Möglichkeit ein Item zu selektieren, ohne dabei die Checkbox zu betätigen.

Deshalb wollte ich im ListBox_SelectionChanged-Event auf das entsprechende Item zugreifen um die "IsChecked"-Eigenschaft der Combobox zu setzen. Und genau hier liegt mein Problem:

Wie kann ich genannten Event auf die Objekte des aktuell selektieren Items zugreifen und diese ändern?

Evtl. ist diese Lösung so auch gar nicht praktikabel? Vielleicht geht das auch einfacher?
Ich brauche einfach eine Liste mit einer Checkbox-Mehrfachauswahl, auf dessen selektierte Items reagiert werden kann.

U
1.578 Beiträge seit 2009
vor 13 Jahren

Wie wäre es wenn du versuchst das IsChecked der Boxen gegen den IsSelected der items Bindest?

Erstelle ein ItemContainertStyle der ein IsSelected zu den Objekten bindet, und im DataTemplate bindest du das IsChecked der Box gegen das IsSelected in den Objekten.

So hättest du theoretisch immer IsChecked und IsSelected in sync und arbeitest im Code nur noch mit IsSelected (was du natürlich auch IsChecked nennen kannst)

X
Xeres Themenstarter:in
16 Beiträge seit 2003
vor 13 Jahren

Danke für die schnelle Antwort 😃

Das war anfangs auch meine Idee, allerdings bin ich an der Bindung-Expression gescheitert. Ich weiß also nicht, wie das Binding geschrieben werden muss bzw. wie ich von Kind auf das Parent bzw. umgekehrt komme.

Könntest du mir hier weiterhelfen?

U
1.578 Beiträge seit 2009
vor 13 Jahren

Wieso Kind-Parent? Ist doch irrelevant.

Nehmen wir an du hast ein Objekt welches in der ListBox dargestellt werden soll, dieses ist als Baum mit Childs
Dieses objekt erweiterst du dann mit dem IsChecked property

public class Item : INotifyPropertyChanged
{
    public Item(string name)
    {
        Name = name;
    }
    public string Name { get; private set; }

    public bool IsChecked
    {
        get { return _isChecked; }
        set
        {
            _isChecked = value;
            OnPropertyChanged("IsChecked");
        }
    }
    private bool _isChecked;
}

Dieses IsChecked repräsentiert nun den Check Status der Box und gleichzeitig das IsSelected dex ListBoxItems
Dafür definiert man dann seine ListBox entsprechend

<ListBox ItemsSource="{Binding Items}">
    <ListBox.ItemContainerStyle>
        <Style TargetType="{x:Type ListBoxItem}">
            <Setter Property="IsSelected" Value="{Binding IsChecked, Mode=TwoWay}" />
        </Style>
    </ListBox.ItemContainerStyle>
    <ListBox.ItemTemplate>
        <DataTemplate>
            <CheckBox IsChecked="{Binding IsChecked}" Content="{Binding Name}" />
        </DataTemplate>
    </ListBox.ItemTemplate>
</ListBox>

Das einzige was mir einfallen würde wäre, sobald ein Item gecheckt ist, ist es auch selectiert, ist das beabsichtigt?
Also der IsSelected status bleibt immer in Sync mit dem IsChecked

Wenn das nicht erwünscht ist, Binde IsSelected beim ListBoxItem Style nicht gegen IsChecked sondern gegen ein IsSelected Property, und im Setter des Properties, sobald es true wird, kannst du IsChecked setzen und so die Checkbox setzen.

Also:

public class Item : INotifyPropertyChanged
{
    public Item(string name)
    {
        Name = name;
    }
    public string Name { get; private set; }

    public bool IsChecked
    {
        get { return _isChecked; }
        set
        {
            _isChecked = value;
            OnPropertyChanged("IsChecked");
        }
    }
    private bool _isChecked;

    public bool IsSelected
    {
        get { return _isSelected; }
        set
        {
            _isSelected= value;
            OnPropertyChanged("IsSelected");
            if (_isSelected)
                IsChecked = true;
        }
    }
    private bool _isSelected;
}

Anm. d. R.: Der Code ist nur Pseudo hier im Forum getippt, muss nicht funktionieren.

5.742 Beiträge seit 2007
vor 13 Jahren

Siehe auch StyleTargetType in SL3 (WindowsPhone 7) -> ohne x:type bei Problemen mit dem Binding im Style unter SL.