0

UI のアイテムのリストに関連付けられている観察可能なコレクションがあります。(observablecollection は UI の項目にバインドされていません)。

これで、ユーザーはアイテムを複数選択し、ドラッグ アンド ドロップで並べ替えることができます。したがって、アイテム1、2、3、4、5、6、7、8がある場合。例として、ユーザーが 4、6、8 を選択し、アイテム 1 と 2 の間に立ち寄ることを選択した場合、新しいリストの順序は次のようになります。

1、4、6、8、2、3、5、7。

Move() 関数を使用して一度だけリストを更新するにはどうすればよいですか?

一度移動したら、リストが別の状態に…?別の配列で古いインデックスを追跡してから移動する必要がありますか? それはこれを行うための最良の方法ですか?提案をありがとう。

4

2 に答える 2

1

CollectionChanged ハンドラーを 1 回だけ発生させることが目的の場合は、ObservableCollection をサブクラス化し (シールされていません)、サイレント更新の前に true に設定した RaiseCollectionChanged という bool プロパティを追加できます。

このコレクション内で実際に移動を実行するメソッドは保護されており、仮想であるため、base.MoveItem (イベントを発生させる) を呼び出す前に RaiseCollectionChanged をオーバーライドしてチェックできます。

サイレント モードでコレクションを変更するときにマークされるフラグを保持することもお勧めします。そうすることで、RaiseCollectionChanged が再び true に設定されたときに、変更されたすべてのアイテムのイベントを一度に発生させることができます。

于 2012-05-29T13:56:02.747 に答える
0

コメントにするには投稿が長すぎるため、回答としてここにあります。Ananthonline
が投稿した ように、ObservableCollection をサブクラス化できます。

しかし、残念ながら、それは作業の半分に過ぎません。その理由は、コレクションがアイテム コントロールのアイテム ソースとしてバインドされるコレクション ビューを暗黙的に使用するためです。

また、WPF のすべての既定のコレクション ビューの基本型として使用されるCollectionViewは、バッチ コレクションの更新をサポートしていません。

private void ValidateCollectionChangedEventArgs(NotifyCollectionChangedEventArgs e)
{
    switch (e.Action)
    {
        case NotifyCollectionChangedAction.Add:
        {
            if (e.NewItems.Count != 1)
            {
                throw new NotSupportedException(SR.Get("RangeActionsNotSupported"));
            }
            break;
        }
        case NotifyCollectionChangedAction.Remove:
        {
            if (e.OldItems.Count != 1)
            {
                throw new NotSupportedException(SR.Get("RangeActionsNotSupported"));
            }
            if (e.OldStartingIndex < 0)
            {
                throw new InvalidOperationException(SR.Get("RemovedItemNotFound"));
            }
            break;
        }
        case NotifyCollectionChangedAction.Replace:
        {
            if (e.NewItems.Count != 1 || e.OldItems.Count != 1)
            {
                throw new NotSupportedException(SR.Get("RangeActionsNotSupported"));
            }
            break;
        }
        case NotifyCollectionChangedAction.Move:
        {
            if (e.NewItems.Count != 1)
            {
                throw new NotSupportedException(SR.Get("RangeActionsNotSupported"));
            }
            if (e.NewStartingIndex < 0)
            {
                throw new InvalidOperationException(SR.Get("CannotMoveToUnknownPosition"));
            }
            break;
        }
        case NotifyCollectionChangedAction.Reset:
        {
            break;
        }
        default:
        {
            throw new NotSupportedException(SR.Get("UnexpectedCollectionChangeAction", new object[]
            {
                e.Action
            }));
        }
    }
}

...そして、ICollectionView を実装する必要があります。これが正しい方法かどうかはわかりません。

于 2012-05-29T18:25:11.910 に答える