Вопрос:
У меня есть набор элементов, отображаемых пользователю.
После двойного щелчка на конкретном элементе я хочу удалить этот элемент из списка.
Я сделал так, что мне не нравится, поскольку это модифицирует источник данных, а не только элементы в списке. Также я понимаю, что в случае, если у меня есть 1000 записей, обновление будет довольно медленным.
Это лучший способ удалить элемент из списка?
Я не хочу изменять источник данных, потому что я тоже буду использовать его для истории.
Установлены фиктивные данные:
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; }
Мой метод элемента удаляется из списка.
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 }
Мое определение списка:
<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> Лучший ответ:
Способ, которым нельзя изменить коллекцию, но удалить отображаемый элемент, выглядит следующим образом:
IEditableCollectionView items = tabControl.Items; //Cast to interface if (items.CanRemove) { items.Remove(tabControl.SelectedItem); }
спасибо за помощь. Я нашел его здесь: WPF: Удалите пунктирную рамку вокруг сфокусированного элемента в стилевом списке
Ответ №1
Лучше используйте подход MVVM и привяжите свой listbox.itemssource к property типа observableCollection<UserNames>.
Таким образом, удалив элементы из observableCollection, элемент будет удален из listbox и пользовательский интерфейс будет автоматически обновляться.
Этот пример показывает привязку PersonList к списку, это может быть полезно для вас.
Ответ №2
MVVM – рекомендуемая модель, но не требуется для ответа на ваш вопрос.
- Внедрить INotifyPropertyChanged
- Измените свой список <> на ObservableCollection <>, как указано
Для другого вопроса об медленном обновлении вы также можете использовать свой список для использования виртуализации, поэтому вместо всего поля рисуются только элементы на экране.
Ответ №3
mvvm рекомендуется, но это должно сработать для вас:
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 }