2
votes

I have a simple ListBox in a WPF app bound to a view model, so the XAML looks like:

<ListBox ItemsSource="{Binding Drivers}"
         SelectedItem="{Binding SelectedDriver, Mode=TwoWay}" />

In my view model, the SelectedDriver is set, so I expect when the view displays, the Driver in the list box which correlates to the SelectedDriver should be highlighted but it is not.

What do I need to do to get the SelectedItem to be highlighted when the SelectedItem value is set in the view model?

SOLVED: Based on the answers below, I realized that while my SelectedDriver object was in fact being set, it did not belong to the Drivers collection. Once I corrected this, it is working as expected. Thanks to all for your input. I don't have enough points to increment the points on answers but thanks very much.

edit: The view model does implement INotifyPropertyChanged. Many other items in the view are properly displayed based on their bindings.

edit: The view model constructor does some housekeeping, and one of the things it does is set up various view elements to prior states. One of those elements is the Drivers list box, so in the view model code, it is being set to an actual item just as you describe: SelectedDriver = Drivers.Where(d => d.Id == savedId) I have verified in Debug that this code is finding the correct Driver and the value of SelectedDriver is correct, it is just not being highlighted in the UI.

2
Is your ViewModel implementing INotifyPropertyChanged?Rohit Vats
At what point in your page lifecycle is your SelectedDriver being set?vidalsasoon

2 Answers

0
votes

All my viewmodels inherit from this ViewModelBase which implements INotifyPropertyChanged. You actually have to call the event handler to notify the UI that the data changed.

public abstract class ViewModelBase : INotifyPropertyChanged
{
    public event PropertyChangedEventHandler PropertyChanged;

    protected virtual void RaisePropertyChanged(string propertyName)
    {
        PropertyChangedEventHandler handler = this.PropertyChanged;
        if (handler != null)
        {
            var e = new PropertyChangedEventArgs(propertyName);
            handler(this, e);
        }
    }
}

So SelectedDriver would look like this:

private Driver selectedDriver;
public Driver SelectedDriver
{
    get { return selectedDriver; }
    set
    {
        selectedDriver = value;
        RaisePropertyChanged("SelectedDriver");
    }
}

If everything is bound properly, and SelectedDriver belongs to a class that inherits from ViewModelBase, this should work. If it doesn't, you might check the output window for bad bindings.

-1
votes

If you want to set the selected item of a collection control from code, then it is customary to set it to an actual item from the collection that is data bound to the ItemsSource property of the control. You can do that easily using LinQ like this:

SelectedDriver = Drivers.Where(d => d.Id == someIdNumber).First();

Alternatively, if you just want to set the first item in the collection as the selected item, then you can do this:

SelectedDriver = Drivers[0];

If that still doesn't work, did you implement the INotifyPropertyChanged interface like @RohitVats suggested?