简体   繁体   中英

Removing Children from a StackPanel

for(int i = 0; i < stackPanel.Children.Count; i++)
{
     stackPanel.Children.Remove(stackPanel.Children[i]);
}
int x  = stackPanel.Children.Count();

After running the above code. The controls are still on the screen. Then x equals 33. So how do I really remove the children?

stackPanel.Children返回一个UIElementCollection,因此您可以像这样使用Clear()

stackPanel.Children.Clear()

Without a good Minimal, Complete, and Verifiable code example , it's impossible to know exactly what your code is doing, never mind explain its behavior with certainty.

However, here are some observations:

  1. Based on the code you posted, I would expect that some children are removed. But because you are removing children at the same time you are varying the index used to identify the children to remove, you are skipping half the children. Eg when i is 0, you remove the first child. But doing so causes the second child to now be the first child. Then you increment i . So the next time through the loop, you don't remove what was originally the second child, you remove what was originally the third child. And so on.

    You could address this by starting your index at the end, and working backwards. Or by just always removing the first child, at index 0 , until the collection is empty. Either way, you can also improve efficiency by using the RemoveAt() method, which removes an element at a specific index, rather than forcing the collection to search until finding the element.

    Of course, there's also the Clear() method. So if you want to remove all of the elements at once, you can use that instead of writing the loop yourself.
  2. You really shouldn't be manipulating the UIElementCollection yourself in the first place. If you have dynamic elements like this, you should instead create a view model class to represent each element in the StackPanel , create instances of that class and add them to eg an ObservableCollection<T> , and then bind that collection to the ItemsSource of an ItemsControl that uses a StackPanel as the ItemsPanel (which ItemsControl does by default).

    Having done that, you then just manipulate the collection as needed to add/remove/rearrange elements. Of course, doing so in a way to avoids the mistake you've made here. :)

Could you also explain why they cannot be removed one by one?

Because you are modifying the same collection that you iterate over. So when you remove the element at index 0 and then increment the loop variable to 1, there is new item at index 0 that will never be removed.

You could solve this by iterating backwards. This works:

for (int i = stackPanel.Children.Count - 1; i >= 0; i--)
{
    stackPanel.Children.Remove(stackPanel.Children[i]);
}
int x = stackPanel.Children.Count;

Or you could just call the stackPanel.Clear() method as suggested by @StanleyS.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM