cpoDesign
cpoDesign

Reputation: 9143

WPF remove listbox item

I have a collection of items displayed to the user.

After double click on specific item, i want to remove this item from the list.

I have done this way that i do not like as this modify data source and not just the items in the list. Also i realise in event that i have some 1000 records, the refresh will be quite slow.

Is here some better way of removing item from listbox?
i do not want to modify datasource because i am going to use it for history too.

Dummy data set up:

    private void SetUpData()
    {
        this.users = new List<UserNames>();
        this.users.Add(new UserNames() {Id = 1, UserName = "name 1"});
        this.users.Add(new UserNames() { Id = 2, UserName = "name 2" });
        this.users.Add(new UserNames() { Id = 3, UserName = "name 3" });
        this.users.Add(new UserNames() { Id = 4, UserName = "name 4" });
        this.users.Add(new UserNames() { Id = 5, UserName = "name 5" });
        this.users.Add(new UserNames() { Id = 6, UserName = "name 6" });
        this.users.Add(new UserNames() { Id = 7, UserName = "name 7" });
        this.users.Add(new UserNames() { Id = 8, UserName = "name 8" });
        this.users.Add(new UserNames() { Id = 9, UserName = "name 9" });
        this.users.Add(new UserNames() { Id = 10, UserName = "name 10" });
        this.listBox1.DataContext = users;
    }

My method of the item being removed from a list.

    private void listBox1_MouseDoubleClick(object sender, MouseButtonEventArgs e)
    {
        UserNames itemToRemove = (UserNames)((ListBox)sender).SelectedItem;
        MessageBox.Show(itemToRemove.UserName);
        this.listBox1.DataContext = null;

        this.users.Remove(itemToRemove); // remove from list
        this.listBox1.DataContext = this.users; // update data source
    }

My listbox definition:

<ListBox Grid.Column="1" Grid.Row="1" Name="listBox1" ItemsSource="{Binding}" SelectedValuePath="Id" MouseDoubleClick="listBox1_MouseDoubleClick">
            <ListBox.ItemTemplate>
                <DataTemplate>
                    <Label Content="{Binding UserName}"  />
                </DataTemplate>
            </ListBox.ItemTemplate>
        </ListBox>

Upvotes: 1

Views: 4656

Answers (4)

MichaelS
MichaelS

Reputation: 7103

Better use the MVVM approach, and bind your listbox.itemssource to a property of type observableCollection<UserNames>.

This way, by removing items from the observableCollection, the item will be removed from the listbox and the UI will be automatically updated.

This example shows a PersonList binding to a listbox, it can be usefull for you.

Upvotes: 1

cpoDesign
cpoDesign

Reputation: 9143

The way how not to alter the collection but remove displayed item is as follows:

IEditableCollectionView items = tabControl.Items; //Cast to interface
if (items.CanRemove)
{
    items.Remove(tabControl.SelectedItem);
}

thank you for your help. i have found it here: WPF: Remove dotted border around focused item in styled listbox

Upvotes: 0

blindmeis
blindmeis

Reputation: 22435

mvvm is recommended but this should work for you:

private void SetUpData()//call this just once
{
    this.users = new ObservableCollection<UserNames>();
    this.users.Add(new UserNames() {Id = 1, UserName = "name 1"});
    this.users.Add(new UserNames() { Id = 2, UserName = "name 2" });
    this.users.Add(new UserNames() { Id = 3, UserName = "name 3" });
    this.users.Add(new UserNames() { Id = 4, UserName = "name 4" });
    this.users.Add(new UserNames() { Id = 5, UserName = "name 5" });
    this.users.Add(new UserNames() { Id = 6, UserName = "name 6" });
    this.users.Add(new UserNames() { Id = 7, UserName = "name 7" });
    this.users.Add(new UserNames() { Id = 8, UserName = "name 8" });
    this.users.Add(new UserNames() { Id = 9, UserName = "name 9" });
    this.users.Add(new UserNames() { Id = 10, UserName = "name 10" });
    this.listBox1.DataContext = users;
}


private void listBox1_MouseDoubleClick(object sender, MouseButtonEventArgs e)
{
    UserNames itemToRemove = (UserNames)((ListBox)sender).SelectedItem;
    MessageBox.Show(itemToRemove.UserName);

    this.users.Remove(itemToRemove); // remove from list
}

Upvotes: 0

tsells
tsells

Reputation: 2771

MVVM is the recommended pattern but not required for the answer to your question.

  1. Implement INotifyPropertyChanged
  2. Change your List<> to an ObservableCollection<> as stated

For the other question about the refresh being slow - you can also use set your listbox to use virtualization so only the items on the screen are drawn instead of the entire box.

Upvotes: 1

Related Questions