tags:

views:

21

answers:

2

I am trying to do something that should be brain-dead simple, however, I cannot get it to work. I am displaying a list of items in a listbox. I have added check boxes to the list box so that the user can select multiple items. However, even though the object in the list being bound to the ListBox has an "IsSelected" property, it is not being bound. I could use some help as this is driving me nuts.

<Style x:Key="CheckBoxListStyle" TargetType="{x:Type ListBox}">
    <Setter Property="SelectionMode" Value="Multiple"></Setter>
    <Setter Property="ItemContainerStyle">
        <Setter.Value>
            <Style TargetType="{x:Type ListBoxItem}">
                <Setter Property="Margin" Value="2"/>
                <Setter Property="Template">
                    <Setter.Value>
                        <ControlTemplate TargetType="{x:Type ListBoxItem}">
                            <CheckBox Focusable="False"
                                        IsChecked="{Binding Path=IsSelected, RelativeSource={RelativeSource TemplatedParent}, Mode=TwoWay}">
                                <ContentPresenter></ContentPresenter>
                            </CheckBox>
                        </ControlTemplate>
                    </Setter.Value>
                </Setter>
            </Style>
        </Setter.Value>
    </Setter>

<ListBox 
                        Style="{StaticResource CheckBoxListStyle}"
                        IsEnabled="{Binding Path=SpecificClients.Value, Mode=OneWay}"
                        ItemsSource="{Binding Path=SelectedClients}"
                        VirtualizingStackPanel.IsVirtualizing="True"
                        VirtualizingStackPanel.VirtualizationMode="Recycling"
                        ScrollViewer.VerticalScrollBarVisibility="Auto"
                        MaxHeight="95">
                </ListBox>

In the View Model I have the following:

public IEnumerable<SelectedClientVM> SelectedClients
....
public class SelectedClientVM
    {
        public bool IsSelected { get; set; }
        public Client Client { get; set; }
        public override string ToString()
        {
            return Client.SearchText;
        }
    }
A: 

This may not be the only issue, but if you want the view to update based on your ViewModel you'll have to implement INotifyPropertyChanged (or something that does a similar job) on your IsSelected property.

Grant Crofton
The problem is that the ViewModel does not get updated by changes in the view.When I want to update the view from the view model, it is a one-time thing, and is handled by manually firing OnPropertychanged("SelectedClients")
Keith
+1  A: 

I think what you want can be better achieved by defining a DataTemplate to be used for each item in the ListBox. A DataTemplate specifies how you want an individual piece of data (a Client in your case) rendered in the ListBox.

Here's my XAML for a simple DataTemplate.

    <DataTemplate x:Key="clientTemplate" DataType="{x:Type local:Client}">
        <Grid>
            <Grid.ColumnDefinitions>
                <ColumnDefinition Width="Auto" />
                <ColumnDefinition />
            </Grid.ColumnDefinitions>
            <CheckBox IsChecked="{Binding IsSelected}" />
            <TextBlock Grid.Column="1" Text="{Binding Name}" Margin="5,0,0,0" />
        </Grid>
    </DataTemplate>

Here's how I referenced it in the ListBox declaration:

<ListBox ItemsSource="{Binding SelectedClients}"
         VirtualizingStackPanel.IsVirtualizing="True"
         ItemTemplate="{StaticResource clientTemplate}" />

Secondly, to Grant's answer, you'll want to be sure that your Client class implements INotifyPropertyChanged. Plus, you'll want to expose your list of Clients using a collection that supports change notifications. I usually use ObservableCollection<T>.

Eric
thanx dude. That nailed it. It was driving me crazy. I tried binding to ListBoxItem in a data template, or use RelativeAncestor, and none of it worked. I never thought of using a data template for the VM type I was using, though now that I see that.... it seems obvious.
Keith
Good, glad that solved it for you. For me, it was definitely a lightbulb-going-off moment once I wrapped my brain around the model.
Eric