diff --git a/v2rayN/v2rayN/Forms/MainForm.Designer.cs b/v2rayN/v2rayN/Forms/MainForm.Designer.cs index 425eebe3..d5f817cf 100644 --- a/v2rayN/v2rayN/Forms/MainForm.Designer.cs +++ b/v2rayN/v2rayN/Forms/MainForm.Designer.cs @@ -185,8 +185,13 @@ this.lvServers.UseCompatibleStateImageBehavior = false; this.lvServers.View = System.Windows.Forms.View.Details; this.lvServers.ColumnClick += new System.Windows.Forms.ColumnClickEventHandler(this.lvServers_ColumnClick); + this.lvServers.ItemDrag += new System.Windows.Forms.ItemDragEventHandler(this.lvServers_ItemDrag); this.lvServers.SelectedIndexChanged += new System.EventHandler(this.lvServers_SelectedIndexChanged); this.lvServers.Click += new System.EventHandler(this.lvServers_Click); + this.lvServers.DragDrop += new System.Windows.Forms.DragEventHandler(this.lvServers_DragDrop); + this.lvServers.DragEnter += new System.Windows.Forms.DragEventHandler(this.lvServers_DragEnter); + this.lvServers.DragOver += new System.Windows.Forms.DragEventHandler(this.lvServers_DragOver); + this.lvServers.DragLeave += new System.EventHandler(this.lvServers_DragLeave); this.lvServers.DoubleClick += new System.EventHandler(this.lvServers_DoubleClick); this.lvServers.KeyDown += new System.Windows.Forms.KeyEventHandler(this.lvServers_KeyDown); // @@ -959,7 +964,7 @@ } -#endregion + #endregion private System.Windows.Forms.GroupBox groupBox1; private System.Windows.Forms.GroupBox gbMsgTitle; diff --git a/v2rayN/v2rayN/Forms/MainForm.cs b/v2rayN/v2rayN/Forms/MainForm.cs index 15733e9c..8947a74b 100644 --- a/v2rayN/v2rayN/Forms/MainForm.cs +++ b/v2rayN/v2rayN/Forms/MainForm.cs @@ -214,6 +214,7 @@ namespace v2rayN.Forms lvServers.View = View.Details; lvServers.Scrollable = true; lvServers.MultiSelect = true; + lvServers.AllowDrop = true; lvServers.HeaderStyle = ColumnHeaderStyle.Clickable; lvServers.Columns.Add("", 30); @@ -313,6 +314,26 @@ namespace v2rayN.Forms } } + /// + /// 填充 ListView 背景颜色 + /// + /// + private void RefillListViewBackColor(ListView listView) + { + for (int i = 0; i < listView.Items.Count; i++) + { + ListViewItem currentItem = lvServers.Items[i]; + if (i % 2 == 1) // 隔行着色 + { + currentItem.BackColor = Color.WhiteSmoke; + } + else + { + currentItem.BackColor = default; + } + } + } + /// /// 刷新托盘服务器菜单 /// @@ -1587,5 +1608,95 @@ namespace v2rayN.Forms } #endregion + #region 拖动排序 + private void lvServers_DragDrop(object sender, DragEventArgs e) + { + int targetIndex = lvServers.InsertionMark.Index; + if (targetIndex == -1) + { + return; + } + if (lvServers.InsertionMark.AppearsAfterItem) + { + targetIndex++; + } + string activeIndexId = config.indexId(); + + lvServers.BeginUpdate(); + foreach (ListViewItem oldItem in lvServers.SelectedItems) + { + if (targetIndex == oldItem.Index) + { + targetIndex++; + continue; + } + VmessItem oldVmess = config.vmess[oldItem.Index]; + + ListViewItem cloneItem = (ListViewItem)oldItem.Clone(); + VmessItem cloneVmess = Utils.DeepCopy(oldVmess); + + lvServers.Items.Insert(targetIndex, cloneItem); + config.vmess.Insert(targetIndex, cloneVmess); + + cloneItem.Selected = true; + if (oldItem.Focused) + { + cloneItem.Focused = true; + } + + lvServers.Items.Remove(oldItem); + config.vmess.Remove(oldVmess); + + targetIndex = lvServers.Items.IndexOf(cloneItem) + 1; + } + + RefillListViewBackColor(lvServers); + lvServers.EndUpdate(); + + config.index = config.FindIndexId(activeIndexId); + ConfigHandler.SaveConfig(ref config, false); + + RefreshServersMenu(); + } + + private void lvServers_DragEnter(object sender, DragEventArgs e) + { + e.Effect = e.AllowedEffect; + } + + private void lvServers_DragLeave(object sender, EventArgs e) + { + lvServers.InsertionMark.Index = -1; + } + + private void lvServers_DragOver(object sender, DragEventArgs e) + { + Point targetPoint = lvServers.PointToClient(new Point(e.X, e.Y)); + int targetIndex = lvServers.InsertionMark.NearestIndex(targetPoint); + + + if (targetIndex > -1) + { + Rectangle itemBounds = lvServers.GetItemRect(targetIndex); + lvServers.EnsureVisible(targetIndex); + + if (targetPoint.Y > itemBounds.Top + (itemBounds.Height / 2)) + { + lvServers.InsertionMark.AppearsAfterItem = true; + } + else + { + lvServers.InsertionMark.AppearsAfterItem = false; + } + } + lvServers.InsertionMark.Index = targetIndex; + } + + private void lvServers_ItemDrag(object sender, ItemDragEventArgs e) + { + lvServers.DoDragDrop(e.Item, DragDropEffects.Move); + } + #endregion + } }