Desktop DragDropSort (#9734)

This commit is contained in:
DHR60
2026-07-14 01:57:00 +00:00
committed by GitHub
parent b9a1c129c4
commit 50ab02e8a9
3 changed files with 117 additions and 97 deletions

View File

@@ -611,9 +611,9 @@
Grid.Column="0" Grid.Column="0"
Margin="{StaticResource Margin4}" Margin="{StaticResource Margin4}"
VerticalAlignment="Center" VerticalAlignment="Center"
Text="{x:Static resx:ResUI.TbSettingsDoubleClick2Activate}" /> Text="{x:Static resx:ResUI.TbSettingsEnableDragDropSort}" />
<ToggleSwitch <ToggleSwitch
x:Name="togDoubleClick2Activate" x:Name="togEnableDragDropSort"
Grid.Row="9" Grid.Row="9"
Grid.Column="1" Grid.Column="1"
Margin="{StaticResource Margin4}" Margin="{StaticResource Margin4}"
@@ -624,15 +624,28 @@
Grid.Column="0" Grid.Column="0"
Margin="{StaticResource Margin4}" Margin="{StaticResource Margin4}"
VerticalAlignment="Center" VerticalAlignment="Center"
Text="{x:Static resx:ResUI.TbSettingsDoubleClick2Activate}" />
<ToggleSwitch
x:Name="togDoubleClick2Activate"
Grid.Row="10"
Grid.Column="1"
Margin="{StaticResource Margin4}"
HorizontalAlignment="Left" />
<TextBlock
Grid.Row="11"
Grid.Column="0"
Margin="{StaticResource Margin4}"
VerticalAlignment="Center"
Text="{x:Static resx:ResUI.TbRootCertificateProvider}" /> Text="{x:Static resx:ResUI.TbRootCertificateProvider}" />
<ComboBox <ComboBox
x:Name="cmbRootCertificateProvider" x:Name="cmbRootCertificateProvider"
Grid.Row="10" Grid.Row="11"
Grid.Column="1" Grid.Column="1"
Width="300" Width="300"
Margin="{StaticResource Margin4}" /> Margin="{StaticResource Margin4}" />
<TextBlock <TextBlock
Grid.Row="10" Grid.Row="11"
Grid.Column="2" Grid.Column="2"
Margin="{StaticResource Margin4}" Margin="{StaticResource Margin4}"
VerticalAlignment="Center" VerticalAlignment="Center"
@@ -866,8 +879,8 @@
Margin="{StaticResource Margin4}" Margin="{StaticResource Margin4}"
HorizontalAlignment="Left" HorizontalAlignment="Left"
VerticalAlignment="Center" VerticalAlignment="Center"
TextWrapping="Wrap" PlaceholderText="proxy_set.sh"
PlaceholderText="proxy_set.sh" /> TextWrapping="Wrap" />
<Button <Button
x:Name="btnBrowseCustomSystemProxyScriptPath" x:Name="btnBrowseCustomSystemProxyScriptPath"
Margin="{StaticResource Margin4}" Margin="{StaticResource Margin4}"
@@ -911,8 +924,8 @@
Margin="{StaticResource Margin4}" Margin="{StaticResource Margin4}"
HorizontalAlignment="Left" HorizontalAlignment="Left"
VerticalAlignment="Center" VerticalAlignment="Center"
TextWrapping="Wrap" PlaceholderText="pac.txt"
PlaceholderText="pac.txt" /> TextWrapping="Wrap" />
<Button <Button
x:Name="btnBrowseCustomSystemProxyPacPath" x:Name="btnBrowseCustomSystemProxyPacPath"
Margin="{StaticResource Margin4}" Margin="{StaticResource Margin4}"

View File

@@ -97,6 +97,7 @@ public partial class OptionSettingWindow : WindowBase<OptionSettingViewModel>
this.Bind(ViewModel, vm => vm.AutoHideStartup, v => v.togAutoHideStartup.IsChecked).DisposeWith(disposables); this.Bind(ViewModel, vm => vm.AutoHideStartup, v => v.togAutoHideStartup.IsChecked).DisposeWith(disposables);
this.Bind(ViewModel, vm => vm.Hide2TrayWhenClose, v => v.togHide2TrayWhenClose.IsChecked).DisposeWith(disposables); this.Bind(ViewModel, vm => vm.Hide2TrayWhenClose, v => v.togHide2TrayWhenClose.IsChecked).DisposeWith(disposables);
this.Bind(ViewModel, vm => vm.MacOSShowInDock, v => v.togMacOSShowInDock.IsChecked).DisposeWith(disposables); this.Bind(ViewModel, vm => vm.MacOSShowInDock, v => v.togMacOSShowInDock.IsChecked).DisposeWith(disposables);
this.Bind(ViewModel, vm => vm.EnableDragDropSort, v => v.togEnableDragDropSort.IsChecked).DisposeWith(disposables);
this.Bind(ViewModel, vm => vm.DoubleClick2Activate, v => v.togDoubleClick2Activate.IsChecked).DisposeWith(disposables); this.Bind(ViewModel, vm => vm.DoubleClick2Activate, v => v.togDoubleClick2Activate.IsChecked).DisposeWith(disposables);
this.Bind(ViewModel, vm => vm.AutoUpdateInterval, v => v.txtautoUpdateInterval.Text).DisposeWith(disposables); this.Bind(ViewModel, vm => vm.AutoUpdateInterval, v => v.txtautoUpdateInterval.Text).DisposeWith(disposables);
this.Bind(ViewModel, vm => vm.CurrentFontFamily, v => v.cmbcurrentFontFamily.Text).DisposeWith(disposables); this.Bind(ViewModel, vm => vm.CurrentFontFamily, v => v.cmbcurrentFontFamily.Text).DisposeWith(disposables);

View File

@@ -1,4 +1,6 @@
using Avalonia.VisualTree;
using DialogHostAvalonia; using DialogHostAvalonia;
using DynamicData.Binding;
using v2rayN.Desktop.Common; using v2rayN.Desktop.Common;
namespace v2rayN.Desktop.Views; namespace v2rayN.Desktop.Views;
@@ -22,14 +24,14 @@ public partial class ProfilesView : ReactiveUserControl<ProfilesViewModel>
lstProfiles.DoubleTapped += LstProfiles_DoubleTapped; lstProfiles.DoubleTapped += LstProfiles_DoubleTapped;
lstProfiles.LoadingRow += LstProfiles_LoadingRow; lstProfiles.LoadingRow += LstProfiles_LoadingRow;
lstProfiles.Sorting += LstProfiles_Sorting; lstProfiles.Sorting += LstProfiles_Sorting;
//if (_config.uiItem.enableDragDropSort) if (_config.UiItem.EnableDragDropSort)
//{ {
// lstProfiles.AllowDrop = true; lstProfiles.SetValue(DragDrop.AllowDropProperty, true);
// lstProfiles.PreviewMouseLeftButtonDown += LstProfiles_PreviewMouseLeftButtonDown;
// lstProfiles.MouseMove += LstProfiles_MouseMove; lstProfiles.AddHandler(PointerPressedEvent, LstProfiles_PointerPressed, RoutingStrategies.Bubble, true);
// lstProfiles.DragEnter += LstProfiles_DragEnter; lstProfiles.AddHandler(DragDrop.DragOverEvent, LstProfiles_DragOver, RoutingStrategies.Bubble);
// lstProfiles.Drop += LstProfiles_Drop; lstProfiles.AddHandler(DragDrop.DropEvent, LstProfiles_Drop, RoutingStrategies.Bubble);
//} }
this.WhenActivated(disposables => this.WhenActivated(disposables =>
{ {
@@ -434,93 +436,97 @@ public partial class ProfilesView : ReactiveUserControl<ProfilesViewModel>
#region Drag and Drop #region Drag and Drop
//private Point startPoint = new(); private static readonly DataFormat<object> LstProfilesRowFormat =
//private int startIndex = -1; DataFormat.CreateInProcessFormat<object>("LstProfilesRow");
//private string formatData = "ProfileItemModel";
///// <summary> private async void LstProfiles_PointerPressed(object? sender, PointerPressedEventArgs e)
///// Helper to search up the VisualTree {
///// </summary> try
///// <typeparam name="T"></typeparam> {
///// <param name="current"></param> if (e.Source is not Visual visualSource)
///// <returns></returns> {
//private static T? FindAncestor<T>(DependencyObject current) where T : DependencyObject return;
//{ }
// do
// {
// if (current is T)
// {
// return (T)current;
// }
// current = VisualTreeHelper.GetParent(current);
// }
// while (current != null);
// return null;
//}
//private void LstProfiles_PreviewMouseLeftButtonDown(object? sender, MouseButtonEventArgs e) var row = visualSource.FindAncestorOfType<DataGridRow>(true);
//{ if (row?.DataContext == null)
// // Get current mouse position {
// startPoint = e.GetPosition(null); return;
//} }
//private void LstProfiles_MouseMove(object? sender, MouseEventArgs e) if (e.GetCurrentPoint(row).Properties.IsLeftButtonPressed)
//{ {
// // Get the current mouse position var dragData = new DataTransfer();
// Point mousePos = e.GetPosition(null); var item = DataTransferItem.Create(LstProfilesRowFormat, row.DataContext);
// Vector diff = startPoint - mousePos; dragData.Add(item);
await DragDrop.DoDragDropAsync(e, dragData, DragDropEffects.Move);
}
}
catch
{
// Ignore
}
}
// if (e.LeftButton == MouseButtonState.Pressed && private void LstProfiles_DragOver(object? sender, DragEventArgs e)
// (Math.Abs(diff.X) > SystemParameters.MinimumHorizontalDragDistance || {
// Math.Abs(diff.Y) > SystemParameters.MinimumVerticalDragDistance)) if (!e.DataTransfer.Contains(LstProfilesRowFormat))
// { {
// // Get the dragged Item e.DragEffects = DragDropEffects.None;
// if (sender is not DataGrid listView) return; return;
// var listViewItem = FindAncestor<DataGridRow>((DependencyObject)e.OriginalSource); }
// if (listViewItem == null) return; // Abort e.DragEffects = DragDropEffects.Move;
// // Find the data behind the ListViewItem }
// ProfileItemModel item = (ProfileItemModel)listView.ItemContainerGenerator.ItemFromContainer(listViewItem);
// if (item == null) return; // Abort
// // Initialize the drag & drop operation
// startIndex = lstProfiles.SelectedIndex;
// DataObject dragData = new(formatData, item);
// DragDrop.DoDragDrop(listViewItem, dragData, DragDropEffects.Copy | DragDropEffects.Move);
// }
//}
//private void LstProfiles_DragEnter(object? sender, DragEventArgs e) private void LstProfiles_Drop(object? sender, DragEventArgs e)
//{ {
// if (!e.Data.GetDataPresent(formatData) || sender != e.Source) if (!e.DataTransfer.Contains(LstProfilesRowFormat))
// { {
// e.Effects = DragDropEffects.None; 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;
}
//private void LstProfiles_Drop(object? sender, DragEventArgs e) var targetRow = visualTarget.FindAncestorOfType<DataGridRow>(true);
//{ if (targetRow is not { DataContext: ProfileItemModel targetItem })
// if (e.Data.GetDataPresent(formatData) && sender == e.Source) {
// { return;
// // Get the drop Item destination }
// if (sender is not DataGrid listView) return; if (ReferenceEquals(sourceItem, targetItem))
// var listViewItem = FindAncestor<DataGridRow>((DependencyObject)e.OriginalSource); {
// if (listViewItem == null) return;
// { }
// // Abort if (lstProfiles.ItemsSource is not IList<ProfileItemModel> items)
// e.Effects = DragDropEffects.None; {
// return; return;
// } }
// // Find the data behind the Item var oldIndex = items.IndexOf(sourceItem);
// ProfileItemModel item = (ProfileItemModel)listView.ItemContainerGenerator.ItemFromContainer(listViewItem); var newIndex = items.IndexOf(targetItem);
// if (item == null) return; if (oldIndex >= 0 && newIndex >= 0)
// // Move item into observable collection {
// // (this will be automatically reflected to lstView.ItemsSource) ViewModel?.MoveServerTo(oldIndex, targetItem);
// e.Effects = DragDropEffects.Move; }
}
// ViewModel?.MoveServerTo(startIndex, item);
// startIndex = -1;
// }
//}
#endregion Drag and Drop #endregion Drag and Drop
} }