在stackpanel WPF中排序元素

时间:2010-03-03 17:10:05

标签: c# wpf sorting stackpanel

我有一个stackpanel,其中包含一些在运行时添加或删除的用户控件。 这些元素有一个索引我分配给他们时,我需要保持这些元素按索引排序,所以我做了一个quicksort函数,根据索引对它们进行排序 但在进行交换的行

          y = items[i]; //y is a temp variable
          items[i] = items[j];

我得到了

“指定的索引已在使用中。首先断开指定索引处的Visual子项”

我尝试将它们复制到临时变量,从集合中删除它们然后使用UIElementCollection中的Insert函数将它们分配到它们的右侧索引,但后来我得到了

“指定的Visual已经是另一个Visual的子项或CompositionTarget的根”

我需要克隆元素或某些东西在某处丢失吗?

4 个答案:

答案 0 :(得分:11)

为什么不使用ListBox / ItemsSontrol并使用CollectionViewSorce / SortDescription来完成这项工作。将元素添加到LayOut面板(如stackpanel)不是一种有效的WPF应用程序。具有垂直方向的StackPanel是ListBox / ItemsControl的默认设置,但是如果您想要一些不同的布局,则可以始终覆盖ListBox.ItemsPanel模板

如果您可以关注 MVVM apporach,则需要在ViewModel类中指定属性(在您的情况下,它将 Index )并设置listBox级别的SortDescription将自动为您提供此功能。您只需添加/删除ObservableCollection绑定到ListBox.ItemsSource,而不是添加和删除实际的UIElements。并指定正确的DataTemplate。

如果您不熟悉CollectionViewSource - http://msdn.microsoft.com/en-us/library/system.windows.data.collectionviewsource.sortdescriptions.aspx

,请检查此项

代码将更像下面..它非常简单。

   <UserControl.Resources>
    <CollectionViewSource x:Key="sourceCollection" Source="{Binding YourObservableCollectionProperty}">
       <CollectionViewSource.SortDescriptions>
        <scm:SortDescription PropertyName="YourProperty-Index"/>
       </CollectionViewSource.SortDescriptions>
     </CollectionViewSource>
   </UserControl.Resources>       

  <ItemsControl ItemsSource="{Binding Source={StaticResource sourceCollection}}"/>

注意:&lt; - 的xmlns:SCM = “CLR-命名空间:System.ComponentModel程序;装配= WindowsBase” - &GT;

答案 1 :(得分:4)

上面的答案是正确的,但是如果你不能改变你的堆叠面板(如果你没有足够的时间,或者写了很多与堆叠面板相关的代码),试试这个:

  1. 将控件存储在列表或词典中
  2. 对列表或词典进行排序
  3. 使用以下方法从stackpanel中删除控件:StackPanel.Children.Remove(child)
  4. List或Dictionary的Foreach成员使用以下命令向StackPanel添加控件:StackPanel.Children.Insert(i,child);
  5. 注意:代码正常工作,Remove函数从StackPanel项目(从树中)删除控件,但控件已经在内存中,因此控件可以插入任何StackPanel或其中。

答案 2 :(得分:1)

如果你想这样做,你需要确保Parent为null,并且你的面板中的索引没有被使用。

如果你只是将它换成临时变量,它仍然是相同的参考。

使用Visual Tree Helper来取消或移动您的UIElement。

答案 3 :(得分:0)

如果给每个元素指定特定名称(即索引)。 删除此控件时,您只需重命名结果控件。

之后,您的所有控件都将被排序。