RemoveAll for ObservableCollections?












59















I am looking for Linq way (like RemoveAll method for List) which can remove selected items from my ObservableCollection.



I am too new to create an extension method for myself. Is there any way I remove items from ObservableCollection passing a Lambda expression?










share|improve this question



























    59















    I am looking for Linq way (like RemoveAll method for List) which can remove selected items from my ObservableCollection.



    I am too new to create an extension method for myself. Is there any way I remove items from ObservableCollection passing a Lambda expression?










    share|improve this question

























      59












      59








      59


      9






      I am looking for Linq way (like RemoveAll method for List) which can remove selected items from my ObservableCollection.



      I am too new to create an extension method for myself. Is there any way I remove items from ObservableCollection passing a Lambda expression?










      share|improve this question














      I am looking for Linq way (like RemoveAll method for List) which can remove selected items from my ObservableCollection.



      I am too new to create an extension method for myself. Is there any way I remove items from ObservableCollection passing a Lambda expression?







      c# observablecollection removeall






      share|improve this question













      share|improve this question











      share|improve this question




      share|improve this question










      asked Feb 25 '11 at 14:41









      Arpit KhandelwalArpit Khandelwal

      76031031




      76031031
























          7 Answers
          7






          active

          oldest

          votes


















          84














          I am not aware of a way to remove only the selected items. But creating an extension method is straight forward:



          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;
          }
          }


          This removes all items from the ObservableCollection that match the condition. You can call it like that:



          var c = new ObservableCollection<SelectableItem>();
          c.Remove(x => x.IsSelected);





          share|improve this answer


























          • Will it be necessary to add itemsToRemove.Clear() before return statement?

            – JoanComasFdz
            Aug 17 '12 at 10:00











          • @JoanComasFdz: No. itemstoRemove will be claimed by the garbage collector.

            – Daniel Hilgarth
            Aug 17 '12 at 10:02






          • 1





            @ShaktiPrakashSingh: Good points. Returning a collection indicates that the original one is unchanged and a new one has been created. As you point out, that is not the case. Furthermore, the method on List<T> returns the count, so it would be a good idea to conform to that. I changed my answer accordingly. Thanks for your comments.

            – Daniel Hilgarth
            Jul 5 '13 at 10:59













          • @DanielHilgarth Thanks a lot, you made my day !

            – Nicolas Bodin-Ripert
            Jul 12 '17 at 13:54





















          38














          Iterating backwards should be more efficient than creating a temporary collection as in Daniel Hilgarth's example.



          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);
          }
          }
          }
          }





          share|improve this answer



















          • 1





            In a real world app under test, I found this was indeed faster than the temp collection - average time of 44ms and peak 62ms vs the temp collection with average time of 55ms and peak 93ms

            – danio
            Jan 18 '16 at 15:44



















          13














          How about this implementation for a one-liner?



          observableCollection.Where(l => l.type == invalid).ToList().All(i => observableCollection.Remove(i))


          -- Edit --



          Sorry, yes, you need a ToList() in the middle to force the first half to evaluate, as LINQ does lazy evaluation by default.






          share|improve this answer


























          • i tried this one but ended up with error: "Collection was modified; enumeration operation may not execute."

            – usefulBee
            Nov 13 '15 at 22:08











          • updated with a fix :)

            – simonalexander2005
            Nov 16 '15 at 10:22











          • That works after the fix. Thank you.

            – usefulBee
            Nov 16 '15 at 19:23











          • I found this to be a very simple/elegant solution. Are there any drawbacks to this over the longer solutions with more up votes?

            – Shimeon
            May 10 '16 at 21:03











          • readability, perhaps. It's not clear on first read what it's doing, whereas the accepted answer splits it into two more obvious parts.

            – simonalexander2005
            May 11 '16 at 9:57



















          9














          Each of solution proposed here which uses routine to remove item one by one has one fault. Imagine that you have many items in observable collection, lets say 10.000 items. Then you want to remove items which meets some condition.



          If you use solution from Daniel Hilgarth and call: c.Remove(x => x.IsSelected); and there are for example 3000 items to be removed, proposed solution will notify about each item removal. This is due to fact that internal implementation of Remove(item) notify about that change. And this will be called for each of 3000 items in removal process.



          So instead of this i created descendant of ObservableCollection and add new method 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));
          }
          }


          Interesting line is itemsToRemove.ForEach(item => Items.Remove(item));. Calling directly Items.Remove(item) will not notify about item removed.



          Instead after removal of required items, changes are notified at once by calls:



          OnPropertyChanged(new PropertyChangedEventArgs("Count"));
          OnPropertyChanged(new PropertyChangedEventArgs("Item"));
          OnCollectionChanged(new NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Reset));





          share|improve this answer


























          • WPF Note: When using this with ItemsControl, the control will call Clear internally when using NotifyCollectionChangedAction.Reset; this resulted in undesired side effects in my specific use case when I had animations on newly added items ~ referencesource.microsoft.com/PresentationFramework/R/…

            – cookbr
            Apr 23 '15 at 14:37






          • 2





            In a real world app under test, I found this was actually slower than the temp collection - average time of 67ms and peak 152ms vs the temp collection with average time of 55ms and peak 93ms. Bear in mind this was only for a small collection though.

            – danio
            Jan 18 '16 at 15:44





















          0














          There is no way to pass an expression to the ObservableCollection to remove matching items, in the same way that a generic list has. ObservableCollection adds and removes one item at a time.



          You will have to create your own implementation of INotifyCollectionChanged in order to do this, or as you mention create an extension method.






          share|improve this answer































            0














            This is my version of an extension method solution, which is only a slight variation on the accepted answer, but has the advantage that the count returned is based on confirmed removal of the item from the collection:



            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);
            }
            }





            share|improve this answer































              0














              ObservableCollection<AppVariable<G>> _appVariables = new new ObservableCollection<AppVariable<G>>();

              var temp = AppRepository.AppVariables.Where(i => i.IsChecked == true).OrderByDescending(k=>k.Index);

              foreach (var i in temp)
              {
              AppRepository.AppVariables.RemoveAt(i.Index);
              }





              share|improve this answer



















              • 1





                please try to add some brief about your answer.

                – Farhana
                Jan 3 at 5:51











              Your Answer






              StackExchange.ifUsing("editor", function () {
              StackExchange.using("externalEditor", function () {
              StackExchange.using("snippets", function () {
              StackExchange.snippets.init();
              });
              });
              }, "code-snippets");

              StackExchange.ready(function() {
              var channelOptions = {
              tags: "".split(" "),
              id: "1"
              };
              initTagRenderer("".split(" "), "".split(" "), channelOptions);

              StackExchange.using("externalEditor", function() {
              // Have to fire editor after snippets, if snippets enabled
              if (StackExchange.settings.snippets.snippetsEnabled) {
              StackExchange.using("snippets", function() {
              createEditor();
              });
              }
              else {
              createEditor();
              }
              });

              function createEditor() {
              StackExchange.prepareEditor({
              heartbeatType: 'answer',
              autoActivateHeartbeat: false,
              convertImagesToLinks: true,
              noModals: true,
              showLowRepImageUploadWarning: true,
              reputationToPostImages: 10,
              bindNavPrevention: true,
              postfix: "",
              imageUploader: {
              brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
              contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
              allowUrls: true
              },
              onDemand: true,
              discardSelector: ".discard-answer"
              ,immediatelyShowMarkdownHelp:true
              });


              }
              });














              draft saved

              draft discarded


















              StackExchange.ready(
              function () {
              StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f5118513%2fremoveall-for-observablecollections%23new-answer', 'question_page');
              }
              );

              Post as a guest















              Required, but never shown

























              7 Answers
              7






              active

              oldest

              votes








              7 Answers
              7






              active

              oldest

              votes









              active

              oldest

              votes






              active

              oldest

              votes









              84














              I am not aware of a way to remove only the selected items. But creating an extension method is straight forward:



              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;
              }
              }


              This removes all items from the ObservableCollection that match the condition. You can call it like that:



              var c = new ObservableCollection<SelectableItem>();
              c.Remove(x => x.IsSelected);





              share|improve this answer


























              • Will it be necessary to add itemsToRemove.Clear() before return statement?

                – JoanComasFdz
                Aug 17 '12 at 10:00











              • @JoanComasFdz: No. itemstoRemove will be claimed by the garbage collector.

                – Daniel Hilgarth
                Aug 17 '12 at 10:02






              • 1





                @ShaktiPrakashSingh: Good points. Returning a collection indicates that the original one is unchanged and a new one has been created. As you point out, that is not the case. Furthermore, the method on List<T> returns the count, so it would be a good idea to conform to that. I changed my answer accordingly. Thanks for your comments.

                – Daniel Hilgarth
                Jul 5 '13 at 10:59













              • @DanielHilgarth Thanks a lot, you made my day !

                – Nicolas Bodin-Ripert
                Jul 12 '17 at 13:54


















              84














              I am not aware of a way to remove only the selected items. But creating an extension method is straight forward:



              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;
              }
              }


              This removes all items from the ObservableCollection that match the condition. You can call it like that:



              var c = new ObservableCollection<SelectableItem>();
              c.Remove(x => x.IsSelected);





              share|improve this answer


























              • Will it be necessary to add itemsToRemove.Clear() before return statement?

                – JoanComasFdz
                Aug 17 '12 at 10:00











              • @JoanComasFdz: No. itemstoRemove will be claimed by the garbage collector.

                – Daniel Hilgarth
                Aug 17 '12 at 10:02






              • 1





                @ShaktiPrakashSingh: Good points. Returning a collection indicates that the original one is unchanged and a new one has been created. As you point out, that is not the case. Furthermore, the method on List<T> returns the count, so it would be a good idea to conform to that. I changed my answer accordingly. Thanks for your comments.

                – Daniel Hilgarth
                Jul 5 '13 at 10:59













              • @DanielHilgarth Thanks a lot, you made my day !

                – Nicolas Bodin-Ripert
                Jul 12 '17 at 13:54
















              84












              84








              84







              I am not aware of a way to remove only the selected items. But creating an extension method is straight forward:



              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;
              }
              }


              This removes all items from the ObservableCollection that match the condition. You can call it like that:



              var c = new ObservableCollection<SelectableItem>();
              c.Remove(x => x.IsSelected);





              share|improve this answer















              I am not aware of a way to remove only the selected items. But creating an extension method is straight forward:



              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;
              }
              }


              This removes all items from the ObservableCollection that match the condition. You can call it like that:



              var c = new ObservableCollection<SelectableItem>();
              c.Remove(x => x.IsSelected);






              share|improve this answer














              share|improve this answer



              share|improve this answer








              edited Jul 5 '13 at 11:00

























              answered Feb 25 '11 at 14:52









              Daniel HilgarthDaniel Hilgarth

              139k33248359




              139k33248359













              • Will it be necessary to add itemsToRemove.Clear() before return statement?

                – JoanComasFdz
                Aug 17 '12 at 10:00











              • @JoanComasFdz: No. itemstoRemove will be claimed by the garbage collector.

                – Daniel Hilgarth
                Aug 17 '12 at 10:02






              • 1





                @ShaktiPrakashSingh: Good points. Returning a collection indicates that the original one is unchanged and a new one has been created. As you point out, that is not the case. Furthermore, the method on List<T> returns the count, so it would be a good idea to conform to that. I changed my answer accordingly. Thanks for your comments.

                – Daniel Hilgarth
                Jul 5 '13 at 10:59













              • @DanielHilgarth Thanks a lot, you made my day !

                – Nicolas Bodin-Ripert
                Jul 12 '17 at 13:54





















              • Will it be necessary to add itemsToRemove.Clear() before return statement?

                – JoanComasFdz
                Aug 17 '12 at 10:00











              • @JoanComasFdz: No. itemstoRemove will be claimed by the garbage collector.

                – Daniel Hilgarth
                Aug 17 '12 at 10:02






              • 1





                @ShaktiPrakashSingh: Good points. Returning a collection indicates that the original one is unchanged and a new one has been created. As you point out, that is not the case. Furthermore, the method on List<T> returns the count, so it would be a good idea to conform to that. I changed my answer accordingly. Thanks for your comments.

                – Daniel Hilgarth
                Jul 5 '13 at 10:59













              • @DanielHilgarth Thanks a lot, you made my day !

                – Nicolas Bodin-Ripert
                Jul 12 '17 at 13:54



















              Will it be necessary to add itemsToRemove.Clear() before return statement?

              – JoanComasFdz
              Aug 17 '12 at 10:00





              Will it be necessary to add itemsToRemove.Clear() before return statement?

              – JoanComasFdz
              Aug 17 '12 at 10:00













              @JoanComasFdz: No. itemstoRemove will be claimed by the garbage collector.

              – Daniel Hilgarth
              Aug 17 '12 at 10:02





              @JoanComasFdz: No. itemstoRemove will be claimed by the garbage collector.

              – Daniel Hilgarth
              Aug 17 '12 at 10:02




              1




              1





              @ShaktiPrakashSingh: Good points. Returning a collection indicates that the original one is unchanged and a new one has been created. As you point out, that is not the case. Furthermore, the method on List<T> returns the count, so it would be a good idea to conform to that. I changed my answer accordingly. Thanks for your comments.

              – Daniel Hilgarth
              Jul 5 '13 at 10:59







              @ShaktiPrakashSingh: Good points. Returning a collection indicates that the original one is unchanged and a new one has been created. As you point out, that is not the case. Furthermore, the method on List<T> returns the count, so it would be a good idea to conform to that. I changed my answer accordingly. Thanks for your comments.

              – Daniel Hilgarth
              Jul 5 '13 at 10:59















              @DanielHilgarth Thanks a lot, you made my day !

              – Nicolas Bodin-Ripert
              Jul 12 '17 at 13:54







              @DanielHilgarth Thanks a lot, you made my day !

              – Nicolas Bodin-Ripert
              Jul 12 '17 at 13:54















              38














              Iterating backwards should be more efficient than creating a temporary collection as in Daniel Hilgarth's example.



              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);
              }
              }
              }
              }





              share|improve this answer



















              • 1





                In a real world app under test, I found this was indeed faster than the temp collection - average time of 44ms and peak 62ms vs the temp collection with average time of 55ms and peak 93ms

                – danio
                Jan 18 '16 at 15:44
















              38














              Iterating backwards should be more efficient than creating a temporary collection as in Daniel Hilgarth's example.



              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);
              }
              }
              }
              }





              share|improve this answer



















              • 1





                In a real world app under test, I found this was indeed faster than the temp collection - average time of 44ms and peak 62ms vs the temp collection with average time of 55ms and peak 93ms

                – danio
                Jan 18 '16 at 15:44














              38












              38








              38







              Iterating backwards should be more efficient than creating a temporary collection as in Daniel Hilgarth's example.



              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);
              }
              }
              }
              }





              share|improve this answer













              Iterating backwards should be more efficient than creating a temporary collection as in Daniel Hilgarth's example.



              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);
              }
              }
              }
              }






              share|improve this answer












              share|improve this answer



              share|improve this answer










              answered Mar 7 '13 at 17:00









              guamsguams

              38132




              38132








              • 1





                In a real world app under test, I found this was indeed faster than the temp collection - average time of 44ms and peak 62ms vs the temp collection with average time of 55ms and peak 93ms

                – danio
                Jan 18 '16 at 15:44














              • 1





                In a real world app under test, I found this was indeed faster than the temp collection - average time of 44ms and peak 62ms vs the temp collection with average time of 55ms and peak 93ms

                – danio
                Jan 18 '16 at 15:44








              1




              1





              In a real world app under test, I found this was indeed faster than the temp collection - average time of 44ms and peak 62ms vs the temp collection with average time of 55ms and peak 93ms

              – danio
              Jan 18 '16 at 15:44





              In a real world app under test, I found this was indeed faster than the temp collection - average time of 44ms and peak 62ms vs the temp collection with average time of 55ms and peak 93ms

              – danio
              Jan 18 '16 at 15:44











              13














              How about this implementation for a one-liner?



              observableCollection.Where(l => l.type == invalid).ToList().All(i => observableCollection.Remove(i))


              -- Edit --



              Sorry, yes, you need a ToList() in the middle to force the first half to evaluate, as LINQ does lazy evaluation by default.






              share|improve this answer


























              • i tried this one but ended up with error: "Collection was modified; enumeration operation may not execute."

                – usefulBee
                Nov 13 '15 at 22:08











              • updated with a fix :)

                – simonalexander2005
                Nov 16 '15 at 10:22











              • That works after the fix. Thank you.

                – usefulBee
                Nov 16 '15 at 19:23











              • I found this to be a very simple/elegant solution. Are there any drawbacks to this over the longer solutions with more up votes?

                – Shimeon
                May 10 '16 at 21:03











              • readability, perhaps. It's not clear on first read what it's doing, whereas the accepted answer splits it into two more obvious parts.

                – simonalexander2005
                May 11 '16 at 9:57
















              13














              How about this implementation for a one-liner?



              observableCollection.Where(l => l.type == invalid).ToList().All(i => observableCollection.Remove(i))


              -- Edit --



              Sorry, yes, you need a ToList() in the middle to force the first half to evaluate, as LINQ does lazy evaluation by default.






              share|improve this answer


























              • i tried this one but ended up with error: "Collection was modified; enumeration operation may not execute."

                – usefulBee
                Nov 13 '15 at 22:08











              • updated with a fix :)

                – simonalexander2005
                Nov 16 '15 at 10:22











              • That works after the fix. Thank you.

                – usefulBee
                Nov 16 '15 at 19:23











              • I found this to be a very simple/elegant solution. Are there any drawbacks to this over the longer solutions with more up votes?

                – Shimeon
                May 10 '16 at 21:03











              • readability, perhaps. It's not clear on first read what it's doing, whereas the accepted answer splits it into two more obvious parts.

                – simonalexander2005
                May 11 '16 at 9:57














              13












              13








              13







              How about this implementation for a one-liner?



              observableCollection.Where(l => l.type == invalid).ToList().All(i => observableCollection.Remove(i))


              -- Edit --



              Sorry, yes, you need a ToList() in the middle to force the first half to evaluate, as LINQ does lazy evaluation by default.






              share|improve this answer















              How about this implementation for a one-liner?



              observableCollection.Where(l => l.type == invalid).ToList().All(i => observableCollection.Remove(i))


              -- Edit --



              Sorry, yes, you need a ToList() in the middle to force the first half to evaluate, as LINQ does lazy evaluation by default.







              share|improve this answer














              share|improve this answer



              share|improve this answer








              edited Feb 10 '17 at 9:04

























              answered Nov 13 '15 at 15:13









              simonalexander2005simonalexander2005

              1,94242957




              1,94242957













              • i tried this one but ended up with error: "Collection was modified; enumeration operation may not execute."

                – usefulBee
                Nov 13 '15 at 22:08











              • updated with a fix :)

                – simonalexander2005
                Nov 16 '15 at 10:22











              • That works after the fix. Thank you.

                – usefulBee
                Nov 16 '15 at 19:23











              • I found this to be a very simple/elegant solution. Are there any drawbacks to this over the longer solutions with more up votes?

                – Shimeon
                May 10 '16 at 21:03











              • readability, perhaps. It's not clear on first read what it's doing, whereas the accepted answer splits it into two more obvious parts.

                – simonalexander2005
                May 11 '16 at 9:57



















              • i tried this one but ended up with error: "Collection was modified; enumeration operation may not execute."

                – usefulBee
                Nov 13 '15 at 22:08











              • updated with a fix :)

                – simonalexander2005
                Nov 16 '15 at 10:22











              • That works after the fix. Thank you.

                – usefulBee
                Nov 16 '15 at 19:23











              • I found this to be a very simple/elegant solution. Are there any drawbacks to this over the longer solutions with more up votes?

                – Shimeon
                May 10 '16 at 21:03











              • readability, perhaps. It's not clear on first read what it's doing, whereas the accepted answer splits it into two more obvious parts.

                – simonalexander2005
                May 11 '16 at 9:57

















              i tried this one but ended up with error: "Collection was modified; enumeration operation may not execute."

              – usefulBee
              Nov 13 '15 at 22:08





              i tried this one but ended up with error: "Collection was modified; enumeration operation may not execute."

              – usefulBee
              Nov 13 '15 at 22:08













              updated with a fix :)

              – simonalexander2005
              Nov 16 '15 at 10:22





              updated with a fix :)

              – simonalexander2005
              Nov 16 '15 at 10:22













              That works after the fix. Thank you.

              – usefulBee
              Nov 16 '15 at 19:23





              That works after the fix. Thank you.

              – usefulBee
              Nov 16 '15 at 19:23













              I found this to be a very simple/elegant solution. Are there any drawbacks to this over the longer solutions with more up votes?

              – Shimeon
              May 10 '16 at 21:03





              I found this to be a very simple/elegant solution. Are there any drawbacks to this over the longer solutions with more up votes?

              – Shimeon
              May 10 '16 at 21:03













              readability, perhaps. It's not clear on first read what it's doing, whereas the accepted answer splits it into two more obvious parts.

              – simonalexander2005
              May 11 '16 at 9:57





              readability, perhaps. It's not clear on first read what it's doing, whereas the accepted answer splits it into two more obvious parts.

              – simonalexander2005
              May 11 '16 at 9:57











              9














              Each of solution proposed here which uses routine to remove item one by one has one fault. Imagine that you have many items in observable collection, lets say 10.000 items. Then you want to remove items which meets some condition.



              If you use solution from Daniel Hilgarth and call: c.Remove(x => x.IsSelected); and there are for example 3000 items to be removed, proposed solution will notify about each item removal. This is due to fact that internal implementation of Remove(item) notify about that change. And this will be called for each of 3000 items in removal process.



              So instead of this i created descendant of ObservableCollection and add new method 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));
              }
              }


              Interesting line is itemsToRemove.ForEach(item => Items.Remove(item));. Calling directly Items.Remove(item) will not notify about item removed.



              Instead after removal of required items, changes are notified at once by calls:



              OnPropertyChanged(new PropertyChangedEventArgs("Count"));
              OnPropertyChanged(new PropertyChangedEventArgs("Item"));
              OnCollectionChanged(new NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Reset));





              share|improve this answer


























              • WPF Note: When using this with ItemsControl, the control will call Clear internally when using NotifyCollectionChangedAction.Reset; this resulted in undesired side effects in my specific use case when I had animations on newly added items ~ referencesource.microsoft.com/PresentationFramework/R/…

                – cookbr
                Apr 23 '15 at 14:37






              • 2





                In a real world app under test, I found this was actually slower than the temp collection - average time of 67ms and peak 152ms vs the temp collection with average time of 55ms and peak 93ms. Bear in mind this was only for a small collection though.

                – danio
                Jan 18 '16 at 15:44


















              9














              Each of solution proposed here which uses routine to remove item one by one has one fault. Imagine that you have many items in observable collection, lets say 10.000 items. Then you want to remove items which meets some condition.



              If you use solution from Daniel Hilgarth and call: c.Remove(x => x.IsSelected); and there are for example 3000 items to be removed, proposed solution will notify about each item removal. This is due to fact that internal implementation of Remove(item) notify about that change. And this will be called for each of 3000 items in removal process.



              So instead of this i created descendant of ObservableCollection and add new method 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));
              }
              }


              Interesting line is itemsToRemove.ForEach(item => Items.Remove(item));. Calling directly Items.Remove(item) will not notify about item removed.



              Instead after removal of required items, changes are notified at once by calls:



              OnPropertyChanged(new PropertyChangedEventArgs("Count"));
              OnPropertyChanged(new PropertyChangedEventArgs("Item"));
              OnCollectionChanged(new NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Reset));





              share|improve this answer


























              • WPF Note: When using this with ItemsControl, the control will call Clear internally when using NotifyCollectionChangedAction.Reset; this resulted in undesired side effects in my specific use case when I had animations on newly added items ~ referencesource.microsoft.com/PresentationFramework/R/…

                – cookbr
                Apr 23 '15 at 14:37






              • 2





                In a real world app under test, I found this was actually slower than the temp collection - average time of 67ms and peak 152ms vs the temp collection with average time of 55ms and peak 93ms. Bear in mind this was only for a small collection though.

                – danio
                Jan 18 '16 at 15:44
















              9












              9








              9







              Each of solution proposed here which uses routine to remove item one by one has one fault. Imagine that you have many items in observable collection, lets say 10.000 items. Then you want to remove items which meets some condition.



              If you use solution from Daniel Hilgarth and call: c.Remove(x => x.IsSelected); and there are for example 3000 items to be removed, proposed solution will notify about each item removal. This is due to fact that internal implementation of Remove(item) notify about that change. And this will be called for each of 3000 items in removal process.



              So instead of this i created descendant of ObservableCollection and add new method 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));
              }
              }


              Interesting line is itemsToRemove.ForEach(item => Items.Remove(item));. Calling directly Items.Remove(item) will not notify about item removed.



              Instead after removal of required items, changes are notified at once by calls:



              OnPropertyChanged(new PropertyChangedEventArgs("Count"));
              OnPropertyChanged(new PropertyChangedEventArgs("Item"));
              OnCollectionChanged(new NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Reset));





              share|improve this answer















              Each of solution proposed here which uses routine to remove item one by one has one fault. Imagine that you have many items in observable collection, lets say 10.000 items. Then you want to remove items which meets some condition.



              If you use solution from Daniel Hilgarth and call: c.Remove(x => x.IsSelected); and there are for example 3000 items to be removed, proposed solution will notify about each item removal. This is due to fact that internal implementation of Remove(item) notify about that change. And this will be called for each of 3000 items in removal process.



              So instead of this i created descendant of ObservableCollection and add new method 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));
              }
              }


              Interesting line is itemsToRemove.ForEach(item => Items.Remove(item));. Calling directly Items.Remove(item) will not notify about item removed.



              Instead after removal of required items, changes are notified at once by calls:



              OnPropertyChanged(new PropertyChangedEventArgs("Count"));
              OnPropertyChanged(new PropertyChangedEventArgs("Item"));
              OnCollectionChanged(new NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Reset));






              share|improve this answer














              share|improve this answer



              share|improve this answer








              edited Oct 23 '14 at 8:05

























              answered Oct 23 '14 at 7:43









              psulekpsulek

              3,38132033




              3,38132033













              • WPF Note: When using this with ItemsControl, the control will call Clear internally when using NotifyCollectionChangedAction.Reset; this resulted in undesired side effects in my specific use case when I had animations on newly added items ~ referencesource.microsoft.com/PresentationFramework/R/…

                – cookbr
                Apr 23 '15 at 14:37






              • 2





                In a real world app under test, I found this was actually slower than the temp collection - average time of 67ms and peak 152ms vs the temp collection with average time of 55ms and peak 93ms. Bear in mind this was only for a small collection though.

                – danio
                Jan 18 '16 at 15:44





















              • WPF Note: When using this with ItemsControl, the control will call Clear internally when using NotifyCollectionChangedAction.Reset; this resulted in undesired side effects in my specific use case when I had animations on newly added items ~ referencesource.microsoft.com/PresentationFramework/R/…

                – cookbr
                Apr 23 '15 at 14:37






              • 2





                In a real world app under test, I found this was actually slower than the temp collection - average time of 67ms and peak 152ms vs the temp collection with average time of 55ms and peak 93ms. Bear in mind this was only for a small collection though.

                – danio
                Jan 18 '16 at 15:44



















              WPF Note: When using this with ItemsControl, the control will call Clear internally when using NotifyCollectionChangedAction.Reset; this resulted in undesired side effects in my specific use case when I had animations on newly added items ~ referencesource.microsoft.com/PresentationFramework/R/…

              – cookbr
              Apr 23 '15 at 14:37





              WPF Note: When using this with ItemsControl, the control will call Clear internally when using NotifyCollectionChangedAction.Reset; this resulted in undesired side effects in my specific use case when I had animations on newly added items ~ referencesource.microsoft.com/PresentationFramework/R/…

              – cookbr
              Apr 23 '15 at 14:37




              2




              2





              In a real world app under test, I found this was actually slower than the temp collection - average time of 67ms and peak 152ms vs the temp collection with average time of 55ms and peak 93ms. Bear in mind this was only for a small collection though.

              – danio
              Jan 18 '16 at 15:44







              In a real world app under test, I found this was actually slower than the temp collection - average time of 67ms and peak 152ms vs the temp collection with average time of 55ms and peak 93ms. Bear in mind this was only for a small collection though.

              – danio
              Jan 18 '16 at 15:44













              0














              There is no way to pass an expression to the ObservableCollection to remove matching items, in the same way that a generic list has. ObservableCollection adds and removes one item at a time.



              You will have to create your own implementation of INotifyCollectionChanged in order to do this, or as you mention create an extension method.






              share|improve this answer




























                0














                There is no way to pass an expression to the ObservableCollection to remove matching items, in the same way that a generic list has. ObservableCollection adds and removes one item at a time.



                You will have to create your own implementation of INotifyCollectionChanged in order to do this, or as you mention create an extension method.






                share|improve this answer


























                  0












                  0








                  0







                  There is no way to pass an expression to the ObservableCollection to remove matching items, in the same way that a generic list has. ObservableCollection adds and removes one item at a time.



                  You will have to create your own implementation of INotifyCollectionChanged in order to do this, or as you mention create an extension method.






                  share|improve this answer













                  There is no way to pass an expression to the ObservableCollection to remove matching items, in the same way that a generic list has. ObservableCollection adds and removes one item at a time.



                  You will have to create your own implementation of INotifyCollectionChanged in order to do this, or as you mention create an extension method.







                  share|improve this answer












                  share|improve this answer



                  share|improve this answer










                  answered Feb 25 '11 at 14:52









                  jjrdkjjrdk

                  1,6091417




                  1,6091417























                      0














                      This is my version of an extension method solution, which is only a slight variation on the accepted answer, but has the advantage that the count returned is based on confirmed removal of the item from the collection:



                      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);
                      }
                      }





                      share|improve this answer




























                        0














                        This is my version of an extension method solution, which is only a slight variation on the accepted answer, but has the advantage that the count returned is based on confirmed removal of the item from the collection:



                        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);
                        }
                        }





                        share|improve this answer


























                          0












                          0








                          0







                          This is my version of an extension method solution, which is only a slight variation on the accepted answer, but has the advantage that the count returned is based on confirmed removal of the item from the collection:



                          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);
                          }
                          }





                          share|improve this answer













                          This is my version of an extension method solution, which is only a slight variation on the accepted answer, but has the advantage that the count returned is based on confirmed removal of the item from the collection:



                          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);
                          }
                          }






                          share|improve this answer












                          share|improve this answer



                          share|improve this answer










                          answered Feb 24 '17 at 11:50









                          Chris PeacockChris Peacock

                          1,5291518




                          1,5291518























                              0














                              ObservableCollection<AppVariable<G>> _appVariables = new new ObservableCollection<AppVariable<G>>();

                              var temp = AppRepository.AppVariables.Where(i => i.IsChecked == true).OrderByDescending(k=>k.Index);

                              foreach (var i in temp)
                              {
                              AppRepository.AppVariables.RemoveAt(i.Index);
                              }





                              share|improve this answer



















                              • 1





                                please try to add some brief about your answer.

                                – Farhana
                                Jan 3 at 5:51
















                              0














                              ObservableCollection<AppVariable<G>> _appVariables = new new ObservableCollection<AppVariable<G>>();

                              var temp = AppRepository.AppVariables.Where(i => i.IsChecked == true).OrderByDescending(k=>k.Index);

                              foreach (var i in temp)
                              {
                              AppRepository.AppVariables.RemoveAt(i.Index);
                              }





                              share|improve this answer



















                              • 1





                                please try to add some brief about your answer.

                                – Farhana
                                Jan 3 at 5:51














                              0












                              0








                              0







                              ObservableCollection<AppVariable<G>> _appVariables = new new ObservableCollection<AppVariable<G>>();

                              var temp = AppRepository.AppVariables.Where(i => i.IsChecked == true).OrderByDescending(k=>k.Index);

                              foreach (var i in temp)
                              {
                              AppRepository.AppVariables.RemoveAt(i.Index);
                              }





                              share|improve this answer













                              ObservableCollection<AppVariable<G>> _appVariables = new new ObservableCollection<AppVariable<G>>();

                              var temp = AppRepository.AppVariables.Where(i => i.IsChecked == true).OrderByDescending(k=>k.Index);

                              foreach (var i in temp)
                              {
                              AppRepository.AppVariables.RemoveAt(i.Index);
                              }






                              share|improve this answer












                              share|improve this answer



                              share|improve this answer










                              answered Jan 3 at 5:30









                              user10860989user10860989

                              1




                              1








                              • 1





                                please try to add some brief about your answer.

                                – Farhana
                                Jan 3 at 5:51














                              • 1





                                please try to add some brief about your answer.

                                – Farhana
                                Jan 3 at 5:51








                              1




                              1





                              please try to add some brief about your answer.

                              – Farhana
                              Jan 3 at 5:51





                              please try to add some brief about your answer.

                              – Farhana
                              Jan 3 at 5:51


















                              draft saved

                              draft discarded




















































                              Thanks for contributing an answer to Stack Overflow!


                              • Please be sure to answer the question. Provide details and share your research!

                              But avoid



                              • Asking for help, clarification, or responding to other answers.

                              • Making statements based on opinion; back them up with references or personal experience.


                              To learn more, see our tips on writing great answers.




                              draft saved


                              draft discarded














                              StackExchange.ready(
                              function () {
                              StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f5118513%2fremoveall-for-observablecollections%23new-answer', 'question_page');
                              }
                              );

                              Post as a guest















                              Required, but never shown





















































                              Required, but never shown














                              Required, but never shown












                              Required, but never shown







                              Required, but never shown

































                              Required, but never shown














                              Required, but never shown












                              Required, but never shown







                              Required, but never shown







                              Popular posts from this blog

                              Angular Downloading a file using contenturl with Basic Authentication

                              Olmecas

                              Can't read property showImagePicker of undefined in react native iOS