Pregunta

Relatively new to C# and MVVM, but I'm making a WP7 app using the MVVM Light Toolkit. I'm having a problem with twoway binding of a property in a ListBox. I have an ObservableCollection of clients and I'm trying to select an individual client (which when clicked will bring me to a new ViewModel).

When I click on a selected item, it should update the SelectedItem property and set the value to the client clicked. However, when clicked it doesn't even get to the setter (I have marked the break point with an *). Does anyone know where I've gone wrong or have a better proposed solution? I have been trawling this place for hours!

XAML MarkUp:

        <ListBox SelectedItem="{Binding SelectedItem, Mode=TwoWay}" ItemsSource="{Binding ClientList, Mode=TwoWay}" x:Name="FirstListBox" Margin="0,0,-12,0" ScrollViewer.VerticalScrollBarVisibility="Auto">
        <ListBox.ItemTemplate>
            <DataTemplate>
                <StackPanel Margin="0,0,0,17" Width="432">
                    <Button CommandParameter="{Binding}">
                        <helper:BindingHelper.Binding>
                            <helper:RelativeSourceBinding Path="ShowClientCommand" TargetProperty="Command"
                                    RelativeMode="ParentDataContext" />
                        </helper:BindingHelper.Binding>
                        <Button.Template>
                            <ControlTemplate>
                                <TextBlock Text="{Binding Name}" TextWrapping="Wrap" Style="{StaticResource PhoneTextExtraLargeStyle}" />
                            </ControlTemplate>
                        </Button.Template>
                    </Button>
                </StackPanel>
            </DataTemplate>
        </ListBox.ItemTemplate>
    </ListBox>

ViewModel Properties:

    public ObservableCollection<Client> ClientList
    {
        get 
        {
            return _clientList;
        }
        set 
        {
            _clientList = value;
            RaisePropertyChanged("ClientList");
        }
    }

    public Client SelectedItem
    {
        get
        {
            return _selectedItem;
        }
        set
        {
         *   _selectedItem = value;
            RaisePropertyChanged("SelectedItem");
        }
    }
¿Fue útil?

Solución

Could it be that because you aren't signed up for the selection_changed event it isn't changing the property?

I'm not completely sure why that isn't working but here's a solution that I always use and that the templates recommend.

Sign your listbox up for the SelectionChanged event like so:

<ListBox SelectionChanged="FirstListBox_SelectionChanged" ItemsSource="{Binding ClientList, Mode=TwoWay}" x:Name="FirstListBox" Margin="0,0,-12,0" ScrollViewer.VerticalScrollBarVisibility="Auto">

Then in the corresponding .cs file, have a handler that looks like this:

private void FirstListBox_SelectionChanged(object sender, SelectionChangedEventArgs e)
{
    // If selected index is -1 (no selection) do nothing
    if (FirstListBox.SelectedIndex == -1)
        return;

    // get the client that's selected
    Client client = (Client) FirstListBox.selectedItem;

    //... do stuff with the client ....

    // reset the index (note this will fire this event again, but
    // it'll automatically return because of the first line
    FirstListBox.SelectedIndex = -1;
}
Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top