From 1242011513231f2fc42cabf1a53011bf283912eb Mon Sep 17 00:00:00 2001 From: DHR60 Date: Sat, 6 Sep 2025 18:50:07 +0800 Subject: [PATCH] avalonia --- .../Views/ProfilesSelectWindow.axaml | 118 +++++++++++++++ .../Views/ProfilesSelectWindow.axaml.cs | 141 ++++++++++++++++++ .../Views/RoutingRuleDetailsWindow.axaml | 15 +- .../Views/RoutingRuleDetailsWindow.axaml.cs | 15 ++ .../v2rayN.Desktop/Views/SubEditWindow.axaml | 12 ++ .../Views/SubEditWindow.axaml.cs | 29 ++++ 6 files changed, 327 insertions(+), 3 deletions(-) create mode 100644 v2rayN/v2rayN.Desktop/Views/ProfilesSelectWindow.axaml create mode 100644 v2rayN/v2rayN.Desktop/Views/ProfilesSelectWindow.axaml.cs diff --git a/v2rayN/v2rayN.Desktop/Views/ProfilesSelectWindow.axaml b/v2rayN/v2rayN.Desktop/Views/ProfilesSelectWindow.axaml new file mode 100644 index 00000000..ada7a7ca --- /dev/null +++ b/v2rayN/v2rayN.Desktop/Views/ProfilesSelectWindow.axaml @@ -0,0 +1,118 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/v2rayN/v2rayN.Desktop/Views/ProfilesSelectWindow.axaml.cs b/v2rayN/v2rayN.Desktop/Views/ProfilesSelectWindow.axaml.cs new file mode 100644 index 00000000..42d34124 --- /dev/null +++ b/v2rayN/v2rayN.Desktop/Views/ProfilesSelectWindow.axaml.cs @@ -0,0 +1,141 @@ +using System.Linq; +using System.Reactive.Disposables; +using System.Threading.Tasks; +using Avalonia; +using Avalonia.Controls; +using Avalonia.Input; +using Avalonia.Interactivity; +using Avalonia.Markup.Xaml; +using Avalonia.ReactiveUI; +using ReactiveUI; +using ServiceLib.Manager; +using v2rayN.Desktop.Common; + +namespace v2rayN.Desktop.Views; + +public partial class ProfilesSelectWindow : ReactiveWindow +{ + private static Config _config; + + public Task ProfileItem => GetFirstProfileItemAsync(); + + public ProfilesSelectWindow() + { + InitializeComponent(); + + _config = AppManager.Instance.Config; + + btnAutofitColumnWidth.Click += BtnAutofitColumnWidth_Click; + txtServerFilter.KeyDown += TxtServerFilter_KeyDown; + lstProfiles.KeyDown += LstProfiles_KeyDown; + lstProfiles.SelectionChanged += LstProfiles_SelectionChanged; + lstProfiles.LoadingRow += LstProfiles_LoadingRow; + lstProfiles.Sorting += LstProfiles_Sorting; + lstProfiles.DoubleTapped += LstProfiles_DoubleTapped; + + ViewModel = new ProfilesSelectViewModel(UpdateViewHandler); + DataContext = ViewModel; + + this.WhenActivated(disposables => + { + this.OneWayBind(ViewModel, vm => vm.ProfileItems, v => v.lstProfiles.ItemsSource).DisposeWith(disposables); + this.Bind(ViewModel, vm => vm.SelectedProfile, v => v.lstProfiles.SelectedItem).DisposeWith(disposables); + + this.Bind(ViewModel, vm => vm.SelectedSub, v => v.lstGroup.SelectedItem).DisposeWith(disposables); + this.Bind(ViewModel, vm => vm.ServerFilter, v => v.txtServerFilter.Text).DisposeWith(disposables); + }); + + btnSave.Click += (s, e) => ViewModel?.SelectFinish(); + btnCancel.Click += (s, e) => Close(false); + } + + private async Task UpdateViewHandler(EViewAction action, object? obj) + { + switch (action) + { + case EViewAction.CloseWindow: + Close(true); + break; + } + return await Task.FromResult(true); + } + + private void LstProfiles_SelectionChanged(object? sender, SelectionChangedEventArgs e) + { + if (ViewModel != null) + { + ViewModel.SelectedProfiles = lstProfiles.SelectedItems.Cast().ToList(); + } + } + + private void LstProfiles_LoadingRow(object? sender, DataGridRowEventArgs e) + { + e.Row.Header = $" {e.Row.Index + 1}"; + } + + private void LstProfiles_DoubleTapped(object? sender, TappedEventArgs e) + { + ViewModel?.SelectFinish(); + } + + private async void LstProfiles_Sorting(object? sender, DataGridColumnEventArgs e) + { + e.Handled = true; + if (ViewModel != null && e.Column?.Tag?.ToString() != null) + { + await ViewModel.SortServer(e.Column.Tag.ToString()); + } + e.Handled = false; + } + + private void LstProfiles_KeyDown(object? sender, KeyEventArgs e) + { + if (e.KeyModifiers is KeyModifiers.Control or KeyModifiers.Meta) + { + if (e.Key == Key.A) + { + lstProfiles.SelectAll(); + } + } + else + { + if (e.Key is Key.Enter or Key.Return) + { + ViewModel?.SelectFinish(); + } + } + } + + private void BtnAutofitColumnWidth_Click(object? sender, RoutedEventArgs e) + { + AutofitColumnWidth(); + } + + private void AutofitColumnWidth() + { + try + { + foreach (var col in lstProfiles.Columns) + { + col.Width = new DataGridLength(1, DataGridLengthUnitType.Auto); + } + } + catch + { + } + } + + private void TxtServerFilter_KeyDown(object? sender, KeyEventArgs e) + { + if (e.Key is Key.Enter or Key.Return) + { + ViewModel?.RefreshServers(); + } + } + + public async Task GetFirstProfileItemAsync() + { + var item = await ViewModel?.GetProfileItem(); + return item; + } +} diff --git a/v2rayN/v2rayN.Desktop/Views/RoutingRuleDetailsWindow.axaml b/v2rayN/v2rayN.Desktop/Views/RoutingRuleDetailsWindow.axaml index f310f260..872a11f8 100644 --- a/v2rayN/v2rayN.Desktop/Views/RoutingRuleDetailsWindow.axaml +++ b/v2rayN/v2rayN.Desktop/Views/RoutingRuleDetailsWindow.axaml @@ -54,13 +54,22 @@ Width="300" Margin="{StaticResource Margin4}" Text="{Binding SelectedSource.OutboundTag, Mode=TwoWay}" /> - + VerticalAlignment="Center"> +