diff --git a/OpenTween/DetailsListView.cs b/OpenTween/DetailsListView.cs index cf6f1ab55..23ad4cb99 100644 --- a/OpenTween/DetailsListView.cs +++ b/OpenTween/DetailsListView.cs @@ -70,15 +70,39 @@ public int SelectionMark public void SelectItems(int[] indices) { - foreach (var index in indices) - { - if (index < 0 || index >= this.VirtualListSize) - throw new ArgumentOutOfRangeException(nameof(indices)); + var listSize = this.VirtualListSize; + if (indices.Any(x => x < 0 || x >= listSize)) + throw new ArgumentOutOfRangeException(nameof(indices)); - NativeMethods.SelectItem(this, index); + if (indices.Length == 0) + { + this.SelectedIndices.Clear(); } + else if (indices.Length == 1) + { + this.SelectedIndices.Clear(); + this.SelectedIndices.Add(indices[0]); + } + else + { + var currentSelectedIndices = this.SelectedIndices.Cast().ToArray(); + var selectIndices = indices.Except(currentSelectedIndices).ToArray(); + var deselectIndices = currentSelectedIndices.Except(indices).ToArray(); - this.OnSelectedIndexChanged(EventArgs.Empty); + if (selectIndices.Length + deselectIndices.Length > currentSelectedIndices.Length) + { + // Clearして選択し直した方が早い場合 + this.SelectedIndices.Clear(); + selectIndices = indices; + deselectIndices = Array.Empty(); + } + + foreach (var index in selectIndices) + NativeMethods.SelectItem(this, index, selected: true); + + foreach (var index in deselectIndices) + NativeMethods.SelectItem(this, index, selected: false); + } } public void SelectAllItems() diff --git a/OpenTween/NativeMethods.cs b/OpenTween/NativeMethods.cs index 209824ff6..6d972c62c 100644 --- a/OpenTween/NativeMethods.cs +++ b/OpenTween/NativeMethods.cs @@ -121,6 +121,7 @@ private struct LVITEM [Flags] private enum LVIS : uint { + None = 0, SELECTED = 0x02, } @@ -130,13 +131,13 @@ private enum LVIS : uint /// 対象となる ListView /// 選択するアイテムのインデックス /// 成功した場合は true、それ以外の場合は false - public static bool SelectItem(ListView listView, int index) + public static bool SelectItem(ListView listView, int index, bool selected = true) { // LVM_SETITEMSTATE では stateMask, state 以外のメンバーは無視される var lvitem = new LVITEM { stateMask = LVIS.SELECTED, - state = LVIS.SELECTED, + state = selected ? LVIS.SELECTED : LVIS.None, }; var ret = (int)SendMessage(listView.Handle, SendMessageType.LVM_SETITEMSTATE, (IntPtr)index, ref lvitem); diff --git a/OpenTween/Tween.cs b/OpenTween/Tween.cs index 5dfc61982..024bccd0b 100644 --- a/OpenTween/Tween.cs +++ b/OpenTween/Tween.cs @@ -9598,11 +9598,6 @@ private void SelectListItem(DetailsListView LView , int[]? Index, int focusedInd if (Index != null) { - do - { - LView.SelectedIndices.Clear(); - } - while (LView.SelectedIndices.Count > 0); LView.SelectItems(Index); } if (selectionMarkIndex > -1 && LView.VirtualListSize > selectionMarkIndex)