Question

I have a WPF application with a ListBox (called listMyItems) which is successfully bound to a class of MyItems that I created. I have a List of MyItems called currentMyItems which is then assigned as ItemSource to the ListBox. It all works fine, if I add an item to the currentMyItems it pops up on the list, etc. The problem occurs when I try to remove the selected item in the ListBox. This is the code that I use:

currentMyItems.Remove((MyItem)listMyItems.SelectedItem);

The item disappears from the ListBox but the next time I update it, it pops back up as it was never deleted. Any tips?

Was it helpful?

Solution

I think you may be confused about how data binding works. When you bind a property, you are telling WPF to go look somewhere else for the value of that property.

When you bind the ListBox.ItemsSource property to currentMyItems, you are telling WPF to go look at the currentMyItems list to find its list of items. If currentMyItems is an ObservableCollection instead of a List<T>, then the UI will automatically receive a notification to update the bound value when you add or remove an item from the collection.

Based on what you say in the question, it sounds like you you have two collections, one of which is bound, and the other which is used to recreate the first collection anytime a change occurs. All that is not needed.

Just create one ObservableCollection<MyItem>, bind it to the ListBox.ItemsSource property, and then add or remove items from that single collection. It should work as you would expect.

<ListBox x:Name="listMyItems" ItemsSource="{Binding MyItems}" />

and

MyItems.Add((MyItem)listMyItems.SelectedItem)
MyItems.Remove((MyItem)listMyItems.SelectedItem)

If you're interested, I also have some beginner articles on my blog for WPF users who are struggling to understand the DataContext. You may want to check out Understanding the change in mindset when switching from WinForms to WPF and What is this “DataContext” you speak of?

OTHER TIPS

If you bound it correctly to an ObservableCollection and currentMyItems is that collection. Than it means that you must have reloaded currentMyItems in meantime.

Also consider binding the SelectedItem property of your ListView - your view model doesn't have to know about the view at all.

Make the currentMyItems<MyItem> an ObservableColection<MyItem>. This way it will raise a property change whenever modified and the UI gets updated accordingly.

Your source collection must be modufy (inherit from IList or ICollection). If your source collection does not support this method of your interface Remove, you can't remove item from source.

So, when you want to remove item you must cast ItemsSource to IList or ICollection:

var source = listbox.ItemsSource as IList ?? listbox.ItemsSource as ICollection;

and then check:

if (source == null) return;

then:

listbox.SelectedItems.ForEach(source.Remove);
listbox.Items.Refresh();

By using ObservableCollection you will automatically get updates on the UI.

You should use an ObservableCollection instead of List. A good thing is to always use ObservableCollection instead of List when something to do with UI

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top