diff --git a/v2rayN/Directory.Packages.props b/v2rayN/Directory.Packages.props
index 292b44f7..d35b38ea 100644
--- a/v2rayN/Directory.Packages.props
+++ b/v2rayN/Directory.Packages.props
@@ -6,8 +6,7 @@
-
-
+
@@ -32,4 +31,4 @@
-
\ No newline at end of file
+
diff --git a/v2rayN/ServiceLib/Handler/ConfigHandler.cs b/v2rayN/ServiceLib/Handler/ConfigHandler.cs
index 3bfa1f23..7daad49b 100644
--- a/v2rayN/ServiceLib/Handler/ConfigHandler.cs
+++ b/v2rayN/ServiceLib/Handler/ConfigHandler.cs
@@ -540,6 +540,67 @@ public static class ConfigHandler
return await Task.FromResult(0);
}
+ public static Task MoveServersTo(
+ Config config,
+ IReadOnlyList orderedProfileIds,
+ IReadOnlyList sourceIndices,
+ int insertIndex)
+ {
+ ArgumentNullException.ThrowIfNull(orderedProfileIds);
+ ArgumentNullException.ThrowIfNull(sourceIndices);
+
+ if (orderedProfileIds.Count == 0 ||
+ sourceIndices.Count == 0 ||
+ insertIndex < 0 ||
+ insertIndex > orderedProfileIds.Count)
+ {
+ return Task.FromResult(-1);
+ }
+
+ int[] movingIndices = sourceIndices
+ .Distinct()
+ .OrderBy(index => index)
+ .ToArray();
+
+ if (movingIndices.Length != sourceIndices.Count ||
+ movingIndices.Any(index =>
+ index < 0 || index >= orderedProfileIds.Count))
+ {
+ return Task.FromResult(-1);
+ }
+
+ var movingIndexSet = movingIndices.ToHashSet();
+
+ var movingIds = movingIndices
+ .Select(index => orderedProfileIds[index])
+ .ToList();
+
+ var remainingIds = orderedProfileIds
+ .Where((_, index) => !movingIndexSet.Contains(index))
+ .ToList();
+
+ if (insertIndex > remainingIds.Count)
+ {
+ return Task.FromResult(-1);
+ }
+
+ remainingIds.InsertRange(insertIndex, movingIds);
+
+ if (remainingIds.Count != orderedProfileIds.Count)
+ {
+ return Task.FromResult(-1);
+ }
+
+ for (var index = 0; index < remainingIds.Count; index++)
+ {
+ ProfileExManager.Instance.SetSort(
+ remainingIds[index],
+ (index + 1) * 10);
+ }
+
+ return Task.FromResult(0);
+ }
+
///
/// Add a custom server configuration from a file
/// Copies the configuration file to the app's config directory
diff --git a/v2rayN/ServiceLib/Resx/ResUI.Designer.cs b/v2rayN/ServiceLib/Resx/ResUI.Designer.cs
index 08a139bb..3c9847f0 100644
--- a/v2rayN/ServiceLib/Resx/ResUI.Designer.cs
+++ b/v2rayN/ServiceLib/Resx/ResUI.Designer.cs
@@ -978,6 +978,15 @@ namespace ServiceLib.Resx {
}
}
+ ///
+ /// 查找类似 Columns 的本地化字符串。
+ ///
+ public static string menuColumns {
+ get {
+ return ResourceManager.GetString("menuColumns", resourceCulture);
+ }
+ }
+
///
/// 查找类似 Close Connection 的本地化字符串。
///
diff --git a/v2rayN/ServiceLib/Resx/ResUI.resx b/v2rayN/ServiceLib/Resx/ResUI.resx
index 39f02c5d..49d63db7 100644
--- a/v2rayN/ServiceLib/Resx/ResUI.resx
+++ b/v2rayN/ServiceLib/Resx/ResUI.resx
@@ -1905,4 +1905,7 @@ The "Get Certificate" action may fail if a self-signed certificate is used or if
Add [MASQUE]
+
+ Columns
+
\ No newline at end of file
diff --git a/v2rayN/ServiceLib/Resx/ResUI.zh-Hans.resx b/v2rayN/ServiceLib/Resx/ResUI.zh-Hans.resx
index 4d97e994..70b03202 100644
--- a/v2rayN/ServiceLib/Resx/ResUI.zh-Hans.resx
+++ b/v2rayN/ServiceLib/Resx/ResUI.zh-Hans.resx
@@ -1897,4 +1897,7 @@
添加 [MASQUE]
+
+ 列
+
\ No newline at end of file
diff --git a/v2rayN/ServiceLib/ViewModels/ProfilesViewModel.cs b/v2rayN/ServiceLib/ViewModels/ProfilesViewModel.cs
index 3d5a291f..0f6c859d 100644
--- a/v2rayN/ServiceLib/ViewModels/ProfilesViewModel.cs
+++ b/v2rayN/ServiceLib/ViewModels/ProfilesViewModel.cs
@@ -702,6 +702,33 @@ public partial class ProfilesViewModel : MyReactiveObject
}
}
+ public async Task MoveServersTo(
+ IReadOnlyList sourceIndices,
+ int insertIndex)
+ {
+ if (sourceIndices.Count == 0 ||
+ insertIndex < 0 ||
+ insertIndex > ProfileItems.Count)
+ {
+ return;
+ }
+
+ var orderedProfileIds = ProfileItems
+ .Select(item => item.IndexId)
+ .ToList();
+
+ var result = await ConfigHandler.MoveServersTo(
+ _config,
+ orderedProfileIds,
+ sourceIndices,
+ insertIndex);
+
+ if (result == 0)
+ {
+ await RefreshServers();
+ }
+ }
+
public async Task ServerSpeedtest(ESpeedActionType actionType)
{
List? lstSelected;
diff --git a/v2rayN/v2rayN.Desktop/App.axaml b/v2rayN/v2rayN.Desktop/App.axaml
index a2de69b6..e64e1613 100644
--- a/v2rayN/v2rayN.Desktop/App.axaml
+++ b/v2rayN/v2rayN.Desktop/App.axaml
@@ -5,6 +5,7 @@
xmlns:dialogHost="clr-namespace:DialogHostAvalonia;assembly=DialogHost.Avalonia"
xmlns:resx="clr-namespace:ServiceLib.Resx;assembly=ServiceLib"
xmlns:semi="https://irihi.tech/semi"
+ xmlns:service="clr-namespace:ServiceLib;assembly=ServiceLib"
xmlns:vms="clr-namespace:ServiceLib.ViewModels;assembly=ServiceLib"
Name="v2rayN"
x:DataType="vms:StatusBarViewModel"
@@ -37,7 +38,7 @@
+ ToolTipText="{Binding RunningServerToolTipText, FallbackValue={x:Static service:Global.AppName}}">
+ SelectionMode="Extended"
+ ShowRowNumbers="True">
@@ -220,11 +222,13 @@
CanUserReorderColumns="False"
CanUserResizeColumns="True"
CanUserSortColumns="False"
+ FrozenColumnCount="2"
GridLinesVisibility="All"
- HeadersVisibility="Column"
+ HeadersVisibility="All"
IsReadOnly="True"
ItemsSource="{Binding AllProfilePreviewItemsObs}"
- SelectionMode="Extended">
+ SelectionMode="Extended"
+ ShowRowNumbers="True">
// Keyboard shortcuts when focus is within grid
AddHandler(KeyDownEvent, AddGroupServerWindow_KeyDown, RoutingStrategies.Tunnel);
- lstChild.LoadingRow += LstChild_LoadingRow;
}
private void InitializeData(ProfileItem profileItem)
@@ -77,11 +76,6 @@ public partial class AddGroupServerWindow : WindowBase
}
}
- private void LstChild_LoadingRow(object? sender, DataGridRowEventArgs e)
- {
- e.Row.Header = $" {e.Row.Index + 1}";
- }
-
private void Window_Loaded(object? sender, RoutedEventArgs e)
{
txtRemarks.Focus();
diff --git a/v2rayN/v2rayN.Desktop/Views/ProfilesSelectWindow.axaml b/v2rayN/v2rayN.Desktop/Views/ProfilesSelectWindow.axaml
index 17eec3ae..3adb5a8b 100644
--- a/v2rayN/v2rayN.Desktop/Views/ProfilesSelectWindow.axaml
+++ b/v2rayN/v2rayN.Desktop/Views/ProfilesSelectWindow.axaml
@@ -71,8 +71,8 @@
Width="200"
Margin="{StaticResource MarginLr4}"
VerticalContentAlignment="Center"
- Text="{Binding ServerFilter, Mode=TwoWay}"
PlaceholderText="{x:Static resx:ResUI.MsgServerTitle}"
+ Text="{Binding ServerFilter, Mode=TwoWay}"
ToolTip.Tip="{x:Static resx:ResUI.MsgServerTitle}" />
@@ -83,11 +83,13 @@
BorderThickness="1"
CanUserReorderColumns="True"
CanUserResizeColumns="True"
+ FrozenColumnCount="2"
GridLinesVisibility="All"
HeadersVisibility="All"
IsReadOnly="True"
ItemsSource="{Binding ProfileItems}"
- SelectionMode="Single">
+ SelectionMode="Single"
+ ShowRowNumbers="True">
diff --git a/v2rayN/v2rayN.Desktop/Views/ProfilesSelectWindow.axaml.cs b/v2rayN/v2rayN.Desktop/Views/ProfilesSelectWindow.axaml.cs
index 6a165d37..22a010dc 100644
--- a/v2rayN/v2rayN.Desktop/Views/ProfilesSelectWindow.axaml.cs
+++ b/v2rayN/v2rayN.Desktop/Views/ProfilesSelectWindow.axaml.cs
@@ -14,7 +14,6 @@ public partial class ProfilesSelectWindow : WindowBase
txtServerFilter.KeyDown += TxtServerFilter_KeyDown;
lstProfiles.KeyDown += LstProfiles_KeyDown;
lstProfiles.SelectionChanged += LstProfiles_SelectionChanged;
- lstProfiles.LoadingRow += LstProfiles_LoadingRow;
lstProfiles.Sorting += LstProfiles_Sorting;
lstProfiles.DoubleTapped += LstProfiles_DoubleTapped;
@@ -61,11 +60,6 @@ public partial class ProfilesSelectWindow : WindowBase
}
}
- private void LstProfiles_LoadingRow(object? sender, DataGridRowEventArgs e)
- {
- e.Row.Header = $" {e.Row.Index + 1}";
- }
-
private void LstProfiles_DoubleTapped(object? sender, TappedEventArgs e)
{
// Ignore double-taps on the column header area
diff --git a/v2rayN/v2rayN.Desktop/Views/ProfilesView.axaml b/v2rayN/v2rayN.Desktop/Views/ProfilesView.axaml
index 305e61b5..2d142e41 100644
--- a/v2rayN/v2rayN.Desktop/Views/ProfilesView.axaml
+++ b/v2rayN/v2rayN.Desktop/Views/ProfilesView.axaml
@@ -16,6 +16,48 @@
mc:Ignorable="d">
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
@@ -79,6 +121,15 @@
+
+
+
+
+
+
+
+
+ IsReadOnly="False"
+ ItemsSource="{Binding ProfileItems}"
+ ShowRowNumbers="True">
@@ -212,12 +270,13 @@
Width="80"
Binding="{Binding ConfigType}"
Header="{x:Static resx:ResUI.LvServiceType}"
+ IsReadOnly="True"
Tag="ConfigType" />
-
-
-
-
+
@@ -240,31 +299,36 @@
Width="120"
Binding="{Binding Address}"
Header="{x:Static resx:ResUI.LvAddress}"
+ IsReadOnly="True"
Tag="Address" />
-
-
-
-
+
-
-
-
-
+
diff --git a/v2rayN/v2rayN.Desktop/Views/ProfilesView.axaml.cs b/v2rayN/v2rayN.Desktop/Views/ProfilesView.axaml.cs
index 43ccba14..2f7e8318 100644
--- a/v2rayN/v2rayN.Desktop/Views/ProfilesView.axaml.cs
+++ b/v2rayN/v2rayN.Desktop/Views/ProfilesView.axaml.cs
@@ -1,4 +1,4 @@
-using Avalonia.VisualTree;
+using Avalonia.Controls.DataGridDragDrop;
using DialogHostAvalonia;
using v2rayN.Desktop.Common;
@@ -8,6 +8,7 @@ public partial class ProfilesView : ReactiveUserControl
{
private static Config _config;
private static readonly string _tag = "ProfilesView";
+ private bool _isDndRegistered = false;
public ProfilesView()
{
@@ -21,18 +22,17 @@ public partial class ProfilesView : ReactiveUserControl
lstProfiles.KeyDown += LstProfiles_KeyDown;
lstProfiles.SelectionChanged += lstProfiles_SelectionChanged;
lstProfiles.DoubleTapped += LstProfiles_DoubleTapped;
- lstProfiles.LoadingRow += LstProfiles_LoadingRow;
lstProfiles.Sorting += LstProfiles_Sorting;
- if (_config.UiItem.EnableDragDropSort)
- {
- lstProfiles.SetValue(DragDrop.AllowDropProperty, true);
+ //if (_config.UiItem.EnableDragDropSort)
+ //{
+ // lstProfiles.SetValue(DragDrop.AllowDropProperty, true);
- lstProfiles.AddHandler(PointerPressedEvent, LstProfiles_PointerPressed, RoutingStrategies.Bubble, true);
- lstProfiles.AddHandler(PointerMovedEvent, LstProfiles_PointerMoved, RoutingStrategies.Bubble, true);
- lstProfiles.AddHandler(PointerReleasedEvent, LstProfiles_PointerReleased, RoutingStrategies.Bubble, true);
- lstProfiles.AddHandler(DragDrop.DragOverEvent, LstProfiles_DragOver, RoutingStrategies.Bubble);
- lstProfiles.AddHandler(DragDrop.DropEvent, LstProfiles_Drop, RoutingStrategies.Bubble);
- }
+ // lstProfiles.AddHandler(PointerPressedEvent, LstProfiles_PointerPressed, RoutingStrategies.Bubble, true);
+ // lstProfiles.AddHandler(PointerMovedEvent, LstProfiles_PointerMoved, RoutingStrategies.Bubble, true);
+ // lstProfiles.AddHandler(PointerReleasedEvent, LstProfiles_PointerReleased, RoutingStrategies.Bubble, true);
+ // lstProfiles.AddHandler(DragDrop.DragOverEvent, LstProfiles_DragOver, RoutingStrategies.Bubble);
+ // lstProfiles.AddHandler(DragDrop.DropEvent, LstProfiles_Drop, RoutingStrategies.Bubble);
+ //}
this.WhenActivated(disposables =>
{
@@ -84,6 +84,22 @@ public partial class ProfilesView : ReactiveUserControl
this.BindCommand(ViewModel, vm => vm.Export2ShareUrlBase64Cmd, v => v.menuExport2ShareUrlBase64).DisposeWith(disposables);
this.BindCommand(ViewModel, vm => vm.Export2InnerUriCmd, v => v.menuExport2InnerUri).DisposeWith(disposables);
+ if (_config.UiItem.EnableDragDropSort && !_isDndRegistered)
+ {
+ lstProfiles.CanUserReorderRows = true;
+ lstProfiles.RowDragHandle = DataGridRowDragHandle.RowHeaderAndRow;
+ lstProfiles.RowDragHandleVisible = true;
+ var rowDragDropOptions = new DataGridRowDragDropOptions()
+ {
+ AllowedEffects = DragDropEffects.Move,
+ DragSelectedRows = true,
+ SuppressSelectionDragFromDragHandle = true,
+ };
+ lstProfiles.RowDragDropOptions = rowDragDropOptions;
+ lstProfiles.RowDropHandler = new ProfileRowDropHandler(ViewModel);
+ _isDndRegistered = true;
+ }
+
ViewModel.ShowYesNoInteraction.RegisterHandler(async interaction =>
{
var message = interaction.Input;
@@ -216,11 +232,6 @@ public partial class ProfilesView : ReactiveUserControl
}
}
- private void LstProfiles_LoadingRow(object? sender, DataGridRowEventArgs e)
- {
- e.Row.Header = $" {e.Row.Index + 1}";
- }
-
//private void LstProfiles_ColumnHeader_Click(object? sender, RoutedEventArgs e)
//{
// var colHeader = sender as DataGridColumnHeader;
@@ -435,140 +446,174 @@ public partial class ProfilesView : ReactiveUserControl
#endregion UI
- #region Drag and Drop
+ //#region Drag and Drop
- private static readonly DataFormat LstProfilesRowFormat =
- DataFormat.CreateInProcessFormat("LstProfilesRow");
+ //private static readonly DataFormat LstProfilesRowFormat =
+ // DataFormat.CreateInProcessFormat("LstProfilesRow");
- private (Point, PointerPressedEventArgs)? _dragStartPoint;
+ //private (Point, PointerPressedEventArgs)? _dragStartPoint;
- private void LstProfiles_PointerPressed(object? sender, PointerPressedEventArgs e)
+ //private void LstProfiles_PointerPressed(object? sender, PointerPressedEventArgs e)
+ //{
+ // var properties = e.GetCurrentPoint(this).Properties;
+ // if (properties.IsLeftButtonPressed)
+ // {
+ // _dragStartPoint = (e.GetPosition(this), e);
+ // }
+ //}
+
+ //private async void LstProfiles_PointerMoved(object? sender, PointerEventArgs e)
+ //{
+ // try
+ // {
+ // if (_dragStartPoint == null)
+ // {
+ // return;
+ // }
+
+ // var properties = e.GetCurrentPoint(this).Properties;
+ // if (!properties.IsLeftButtonPressed)
+ // {
+ // _dragStartPoint = null;
+ // return;
+ // }
+
+ // var currentPoint = e.GetPosition(this);
+ // var startPoint = _dragStartPoint.Value.Item1;
+ // var delta = startPoint - currentPoint;
+
+ // var threshold = new Vector(4, 4);
+
+ // if (!(Math.Abs(delta.X) >= threshold.X) && !(Math.Abs(delta.Y) >= threshold.Y))
+ // {
+ // return;
+ // }
+ // var dragStartEventArgs = _dragStartPoint.Value.Item2;
+ // _dragStartPoint = null;
+
+ // if (e.Source is not Visual visualSource)
+ // {
+ // return;
+ // }
+ // var row = visualSource.FindAncestorOfType(true);
+ // if (row?.DataContext == null)
+ // {
+ // return;
+ // }
+
+ // e.Handled = true;
+
+ // var dragData = new DataTransfer();
+ // var item = DataTransferItem.Create(LstProfilesRowFormat, row.DataContext as ProfileItemModel);
+
+ // dragData.Add(item);
+
+ // await DragDrop.DoDragDropAsync(dragStartEventArgs, dragData, DragDropEffects.Move);
+ // }
+ // catch
+ // {
+ // // Ignore
+ // }
+ //}
+
+ //private void LstProfiles_PointerReleased(object? sender, PointerReleasedEventArgs e)
+ //{
+ // _dragStartPoint = null;
+ //}
+
+ //private void LstProfiles_DragOver(object? sender, DragEventArgs e)
+ //{
+ // if (!e.DataTransfer.Contains(LstProfilesRowFormat))
+ // {
+ // e.DragEffects = DragDropEffects.None;
+ // return;
+ // }
+ // e.DragEffects = DragDropEffects.Move;
+ //}
+
+ //private void LstProfiles_Drop(object? sender, DragEventArgs e)
+ //{
+ // if (!e.DataTransfer.Contains(LstProfilesRowFormat))
+ // {
+ // return;
+ // }
+ // ProfileItemModel? sourceItem = null;
+ // foreach (var item in e.DataTransfer.Items)
+ // {
+ // if (!item.Formats.Contains(LstProfilesRowFormat))
+ // {
+ // continue;
+ // }
+ // if (item.TryGetRaw(LstProfilesRowFormat) is not ProfileItemModel model)
+ // {
+ // continue;
+ // }
+ // sourceItem = model;
+ // break;
+ // }
+ // if (sourceItem == null)
+ // {
+ // return;
+ // }
+ // if (e.Source is not Visual visualTarget)
+ // {
+ // return;
+ // }
+
+ // var targetRow = visualTarget.FindAncestorOfType(true);
+ // if (targetRow is not { DataContext: ProfileItemModel targetItem })
+ // {
+ // return;
+ // }
+ // if (ReferenceEquals(sourceItem, targetItem))
+ // {
+ // return;
+ // }
+ // if (lstProfiles.ItemsSource is not IList items)
+ // {
+ // return;
+ // }
+ // var oldIndex = items.IndexOf(sourceItem);
+ // var newIndex = items.IndexOf(targetItem);
+ // if (oldIndex >= 0 && newIndex >= 0)
+ // {
+ // ViewModel?.MoveServerTo(oldIndex, targetItem);
+ // }
+ //}
+
+ //#endregion Drag and Drop
+
+ private sealed class ProfileRowDropHandler(ProfilesViewModel viewModel) : IDataGridRowDropHandler
{
- var properties = e.GetCurrentPoint(this).Properties;
- if (properties.IsLeftButtonPressed)
+ private readonly DataGridRowReorderHandler _reorderHandler = new();
+
+ public bool Validate(DataGridRowDropEventArgs args)
{
- _dragStartPoint = (e.GetPosition(this), e);
+ ArgumentNullException.ThrowIfNull(args);
+ return _reorderHandler.Validate(args);
+ }
+
+ public bool Execute(DataGridRowDropEventArgs args)
+ {
+ ArgumentNullException.ThrowIfNull(args);
+
+ if (!_reorderHandler.Execute(args))
+ {
+ return false;
+ }
+
+ if (viewModel?.ProfileItems != null)
+ {
+ for (var index = 0; index < viewModel.ProfileItems.Count; index++)
+ {
+ var item = viewModel.ProfileItems[index];
+ var sort = (index + 1) * 10;
+ item.Sort = sort;
+ ProfileExManager.Instance.SetSort(item.IndexId, sort);
+ }
+ }
+
+ return true;
}
}
-
- private async void LstProfiles_PointerMoved(object? sender, PointerEventArgs e)
- {
- try
- {
- if (_dragStartPoint == null)
- {
- return;
- }
-
- var properties = e.GetCurrentPoint(this).Properties;
- if (!properties.IsLeftButtonPressed)
- {
- _dragStartPoint = null;
- return;
- }
-
- var currentPoint = e.GetPosition(this);
- var startPoint = _dragStartPoint.Value.Item1;
- var delta = startPoint - currentPoint;
-
- var threshold = new Vector(4, 4);
-
- if (!(Math.Abs(delta.X) >= threshold.X) && !(Math.Abs(delta.Y) >= threshold.Y))
- {
- return;
- }
- var dragStartEventArgs = _dragStartPoint.Value.Item2;
- _dragStartPoint = null;
-
- if (e.Source is not Visual visualSource)
- {
- return;
- }
- var row = visualSource.FindAncestorOfType(true);
- if (row?.DataContext == null)
- {
- return;
- }
-
- e.Handled = true;
-
- var dragData = new DataTransfer();
- var item = DataTransferItem.Create(LstProfilesRowFormat, row.DataContext as ProfileItemModel);
-
- dragData.Add(item);
-
- await DragDrop.DoDragDropAsync(dragStartEventArgs, dragData, DragDropEffects.Move);
- }
- catch
- {
- // Ignore
- }
- }
-
- private void LstProfiles_PointerReleased(object? sender, PointerReleasedEventArgs e)
- {
- _dragStartPoint = null;
- }
-
- private void LstProfiles_DragOver(object? sender, DragEventArgs e)
- {
- if (!e.DataTransfer.Contains(LstProfilesRowFormat))
- {
- e.DragEffects = DragDropEffects.None;
- return;
- }
- e.DragEffects = DragDropEffects.Move;
- }
-
- private void LstProfiles_Drop(object? sender, DragEventArgs e)
- {
- if (!e.DataTransfer.Contains(LstProfilesRowFormat))
- {
- return;
- }
- ProfileItemModel? sourceItem = null;
- foreach (var item in e.DataTransfer.Items)
- {
- if (!item.Formats.Contains(LstProfilesRowFormat))
- {
- continue;
- }
- if (item.TryGetRaw(LstProfilesRowFormat) is not ProfileItemModel model)
- {
- continue;
- }
- sourceItem = model;
- break;
- }
- if (sourceItem == null)
- {
- return;
- }
- if (e.Source is not Visual visualTarget)
- {
- return;
- }
-
- var targetRow = visualTarget.FindAncestorOfType(true);
- if (targetRow is not { DataContext: ProfileItemModel targetItem })
- {
- return;
- }
- if (ReferenceEquals(sourceItem, targetItem))
- {
- return;
- }
- if (lstProfiles.ItemsSource is not IList items)
- {
- return;
- }
- var oldIndex = items.IndexOf(sourceItem);
- var newIndex = items.IndexOf(targetItem);
- if (oldIndex >= 0 && newIndex >= 0)
- {
- ViewModel?.MoveServerTo(oldIndex, targetItem);
- }
- }
-
- #endregion Drag and Drop
}
diff --git a/v2rayN/v2rayN.Desktop/v2rayN.Desktop.csproj b/v2rayN/v2rayN.Desktop/v2rayN.Desktop.csproj
index fb2274e8..fb8d9ba7 100644
--- a/v2rayN/v2rayN.Desktop/v2rayN.Desktop.csproj
+++ b/v2rayN/v2rayN.Desktop/v2rayN.Desktop.csproj
@@ -16,12 +16,10 @@
-
- true
-
+