Как и другие люди, вам нужно сделать:
myDropDown.Items.Remove (ListItem li);
, но если вы хотите, чтобы страница обновлялась асинхронно, выпадающее меню должно быть внутри asp: UpdatePanel
после того, как вы Удалить вызов
, вам нужно позвонить:
yourPanel.Update ();
Я не знаю, как удалить только выбранные элементы. Но создание метода расширения прямолинейно:
public static class ExtensionMethods
{
public static int Remove<T>(
this ObservableCollection<T> coll, Func<T, bool> condition)
{
var itemsToRemove = coll.Where(condition).ToList();
foreach (var itemToRemove in itemsToRemove)
{
coll.Remove(itemToRemove);
}
return itemsToRemove.Count;
}
}
Это удаляет все элементы из ObservableCollection
, которые соответствуют условию. Вы можете так называть:
var c = new ObservableCollection<SelectableItem>();
c.Remove(x => x.IsSelected);
Итерация назад должна быть более эффективной, чем создание временной коллекции, как в примере Даниэля Хильгарта.
public static class ObservableCollectionExtensions
{
public static void RemoveAll<T>(this ObservableCollection<T> collection,
Func<T, bool> condition)
{
for (int i = collection.Count - 1; i >= 0; i--)
{
if (condition(collection[i]))
{
collection.RemoveAt(i);
}
}
}
}
Каждое предлагаемое здесь решение, которое использует процедуру для удаления элемента один за другим, имеет одну ошибку. Представьте, что у вас много предметов в наблюдаемой коллекции, скажем 10.000 предметов. Затем вы хотите удалить элементы, которые удовлетворяют некоторому условию.
Если вы используете решение из Daniel Hilgarth
и звоните: c.Remove(x => x.IsSelected);
и, например, 3000 предметов, которые нужно удалить, предлагаемое решение сообщит об удалении каждого элемента. Это связано с тем, что внутренняя реализация Remove(item)
уведомляет об этом изменении. И это будет вызвано для каждого из 3000 элементов в процессе удаления.
Поэтому вместо этого я создал потомка ObservableCollection и добавил новый метод RemoveAll(predicate)
[Serializable]
public class ObservableCollectionExt<T> : ObservableCollection<T>
{
public void RemoveAll(Predicate<T> predicate)
{
CheckReentrancy();
List<T> itemsToRemove = Items.Where(x => predicate(x)).ToList();
itemsToRemove.ForEach(item => Items.Remove(item));
OnPropertyChanged(new PropertyChangedEventArgs("Count"));
OnPropertyChanged(new PropertyChangedEventArgs("Item[]"));
OnCollectionChanged(new NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Reset));
}
}
Интересная строка itemsToRemove.ForEach(item => Items.Remove(item));
. Вызов напрямую Items.Remove(item)
не будет уведомлять об удалении элемента.
Вместо этого после удаления необходимых элементов изменения сообщаются сразу по вызовам:
OnPropertyChanged(new PropertyChangedEventArgs("Count"));
OnPropertyChanged(new PropertyChangedEventArgs("Item[]"));
OnCollectionChanged(new NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Reset));
Как насчет этой реализации для одного слоя?
observableCollection.Where(l => l.type == invalid).ToList().All(i => observableCollection.Remove(i))
- Изменить -
К сожалению, вам нужен ToList () в середине, чтобы заставить первая половина для оценки, поскольку LINQ делает ленивую оценку по умолчанию.
Это моя версия решения метода расширения, которое является лишь небольшим изменением принятого ответа, но имеет то преимущество, что возвращенный счет основан на подтвержденном удалении элемента из коллекции :
public static class ObservableCollectionExtensionMethods
{
/// <summary>
/// Extends ObservableCollection adding a RemoveAll method to remove elements based on a boolean condition function
/// </summary>
/// <typeparam name="T">The type contained by the collection</typeparam>
/// <param name="observableCollection">The ObservableCollection</param>
/// <param name="condition">A function that evaluates to true for elements that should be removed</param>
/// <returns>The number of elements removed</returns>
public static int RemoveAll<T>(this ObservableCollection<T> observableCollection, Func<T, bool> condition)
{
// Find all elements satisfying the condition, i.e. that will be removed
var toRemove = observableCollection
.Where(condition)
.ToList();
// Remove the elements from the original collection, using the Count method to iterate through the list,
// incrementing the count whenever there's a successful removal
return toRemove.Count(observableCollection.Remove);
}
}
itemstoRemove
будет востребован сборщиком мусора. – Daniel Hilgarth 17 August 2012 в 11:02List<T>
возвращает счет, поэтому было бы неплохо соответствовать этому. Я изменил свой ответ соответственно. Спасибо за ваши комментарии. – Daniel Hilgarth 5 July 2013 в 11:59