列表資料需支援「多選、拖曳排序」,選取項目可能包含多個連續區塊(如 Key0、Key2~Key4、Key9),需一次性上移/下移並維持區塊內部相對順序。
MoveSeqArithmeticItem<T, K>:包裝業務物件,含 Seq (排序號)、ObjKey (業務鍵)、PreviewItem/BackItem (雙向鏈表指標)、AfterSetSequenceEvent。SequenceAreaEntity:連續區塊實體,含 FItem (首項)、LItem (尾項)、ArrAreas (區塊內所有項)。MoveSeqArithmetic<T, K>:演算法核心,維護項目陣列與鏈表關係。
public void MoveUpByKeys(object[] objKeys)
{
// 1. 依鍵值分組連續區塊 → Hashtable
var areas = GetSequenceAreasByKeys(objKeys);
foreach (var area in areas.Values)
{
// 2. 找到區塊前一個項目 (移動目標位置)
var moveItem = GetPreviewItemByArea(area);
if (moveItem == null) continue; // 已在最頂
int moveIdx = moveItem.Seq;
int firstIdx = area.FItem.Seq;
int lastIdx = area.LItem.Seq;
// 3. 區塊內所有項 Seq 往前平移 (壓縮空隙)
foreach (var item in area.ArrAreas)
item.Seq = item.Seq - firstIdx + moveIdx;
// 4. 將區塊尾項 Seq 設為原移動目標位置 (完成置換)
moveItem.Seq = lastIdx;
// 5. 修復雙向鏈表指標
area.FItem.PreviewItem = moveItem.PreviewItem;
moveItem.PreviewItem = area.LItem;
moveItem.BackItem = area.LItem.BackItem;
area.LItem.BackItem = moveItem;
}
Sort(); // 依 Seq 重新排序陣列
}
邏輯鏡像:尋找區塊後一個項目 (GetNextItemByArea),區塊項 Seq 往後平移,修復鏈表。
// 初始: Key0 Key1 Key2 Key3 Key4 Key5 Key6 Key7 Key8 Key9
// 上移 Key0, Key2~Key4, Key9
// 結果: Key0 Key2 Key3 Key4 Key1 Key5 Key6 Key7 Key8 Key9
// 下移 Key0, Key1~Key3, Key9
// 結果: Key1 Key2 Key3 Key0 Key4 Key5 Key6 Key7 Key8 Key9
SequenceAreaEntity 將離散選轉化為連續區塊集合,統一處理邏輯。Sort() 同步兩者。AfterSetSequenceEvent 讓 UI 即時更新顯示順序。<T, K> 適配任意業務物件與鍵型別。將「多選拖曳排序」抽象為「連續區塊平移 + 鏈表修復」,以 Seq 為唯一排序依據,實現了高內聚、低耦合的通用移動演算法。可直接套用於 Grid、Tree、List 等各類可排序元件。