0
votes

I've got a Windows Phone app with a ListPicker bound to an ObservableCollection and a selected item:

<toolkit:ListPicker Header="Endgame condition" ItemsSource="{Binding Conditions}" 
                    SelectedItem="{Binding SelectedCondition, Mode=TwoWay}" />

And in the ViewModel:

public ObservableCollection<string> Conditions
{
    get { return conditions; }
}

public string SelectedCondition
{
    get { return selectedCondition; }
    set
    {
        if (selectedCondition != value)
        {
            selectedCondition = value;
            OnPropertyChanged("SelectedCondition");
        } 
    }
}

When I try to remove the selected item from the list in a button handler, I get an InvalidOperationException (SelectedItem must always be set to a valid value):

public void ConfirmCondition()
{
    var selected = selectedCondition;
    SelectedCondition = null;

    // throws an exception: SelectedItem must always be set to a valid value
    conditions.Remove(selected);
}

I was hoping that setting the SelectedCondition to null (which is actually the first item in the list), would fix it, but it doesn't. It appears that the NotifyPropertyChanged on the SelectedCondition (which is bound to the ListPicker's SelectedItem with a TwoWay binding mode) doesn't update the SelectedItem before the Remove triggers a CollectionChanged notification for the ItemsSource.

Any ideas how I can remove the item without getting the exception?

2
What is this Exception that you only just mention in your very last sentence?Sheridan
@Sheridan: I've clarified the problem. It was an InvalidOperationException (see comment in the code).Jackson Pope

2 Answers

1
votes

While I can't be 100% certain based on the code you've shown it's probably because the "selected" item isn't actually a member of the "conditions" collection.

Because you're using a separate object to track which of the collection is selected you'll need to find the equivalent item in the collection and delete that instead. (You can't remove an item from a collection which isn't in the collection in the first place. Even if they are represented in the same way on screen.)

Try something like this.

foreach(var item in conditions)
{
    if(item.Equals(selectedCondition))
    {
        conditions.Remove(item);
    }
}

(Make sure Equals is suitably capable of correctly determining the correct instance in the collection.)

0
votes
public ObservableCollection<string> Conditions
{
    get { return conditions; }
    set { return contitions;
    OnPropertyChanged("SelectedCondition");
    }
}

public void ConfirmCondition()
{
    if(SelectedCondition != null){
    conditions.Remove(SelectedCondition );
    }
}

work? @Matt Lacey If you add item like you remove item you don't need to parse ObservableCollection.