8

実行時に追加または削除されるいくつかのユーザーコントロールを備えたスタックパネルがあります。これらの要素には、新しい要素に割り当てるインデックスがあります。これらの要素をそのインデックスで並べ替えておく必要があるため、インデックスに基づいて、スワッピングを行う行に基づいて並べ替えるクイックソート関数を使用しました。

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

私は得る

「指定されたインデックスはすでに使用されています。最初に指定されたインデックスでVisualの子を切断してください」

それらを一時変数にコピーし、コレクションから削除してから、UIElementCollectionのInsert関数を使用して正しいインデックスに割り当てようとしましたが、

「指定されたビジュアルは、すでに別のビジュアルの子またはCompositionTargetのルートです」

必要なクローン要素や、どこかに欠けているものはありますか?

4

4 に答える 4

11

ListBox / ItemsSontrolを使用し、CollectionViewSorce/SortDescriptionを使用してこの作業を実行しないのはなぜですか。stackpanelなどの要素をLayOutPanelに追加することは、WPFアプリで効率的に行う方法ではありません。垂直方向のStackPanelがListBox/ItemsControlのデフォルトですが、別のレイアウトが必要な場合は、いつでもListBox.ItemsPanelテンプレートをオーバーライドできます。

MVVMアプローチに従うことができる場合は、ViewModelクラスでプロパティ(この場合はIndex)を指定し、listBoxレベルでSortDescriptionを設定すると、この機能が自動的に提供されます。実際のUIElementを追加および削除する代わりに、ListBox.ItemsSourceへのObservableCollectionバインドに追加/削除するだけで済みます。そして、適切な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}}"/>

注:<-xmlns:scm = "clr-namespace:System.ComponentModel; assembly = WindowsBase"->

于 2010-03-03T17:14:37.927 に答える
5

上記の答えは正しいですが、スタックパネルを変更できない場合(十分な時間がない場合、またはスタックパネルに関連する多くのコードを記述した場合)は、次のことを試してください。

  1. コントロールをリストまたは辞書に保存する
  2. リストまたは辞書を並べ替える
  3. StackPanel.Children.Remove(child)を使用してstackpanelからコントロールを削除します
  4. ListまたはDictionaryのForeachメンバーは、次を使用してStackPanelにコントロールを追加します。StackPanel.Children.Insert(i、child);

注:コードは機能しています。削除関数はStackPanelアイテムから(ツリーから)コントロールを削除しますが、コントロールはすでにメモリ上にあるため、コントロールは任意のStackPanelまたは同じものに挿入できます。

于 2011-08-19T16:35:53.680 に答える
1

これを行う場合は、親がnullであること、およびパネルへのインデックスが使用されていないことを確認する必要があります。

それを一時変数にスワップするだけでも、それは同じ参照です。

UIElementを識別または移動するには、ビジュアルツリーヘルパーを使用します。

于 2010-03-03T17:56:44.243 に答える
0

各要素に特定の名前(インデックス)を付ける場合。このコントロールを削除すると、結果コントロールの名前を変更できます。

その後、すべてのコントロールが並べ替えられます。

于 2010-03-03T17:45:36.607 に答える