pull/7891/head
DHR60 2025-09-06 19:19:34 +08:00
parent e6c57fcac0
commit f11b46ed37
5 changed files with 103 additions and 11 deletions

View File

@ -277,6 +277,33 @@ public class ProfilesSelectViewModel : MyReactiveObject
return item; return item;
} }
public async Task<List<ProfileItem>?> GetProfileItems()
{
if (SelectedProfiles == null || SelectedProfiles.Count == 0)
{
return null;
}
var lst = new List<ProfileItem>();
foreach (var sp in SelectedProfiles)
{
if (string.IsNullOrEmpty(sp?.IndexId))
{
continue;
}
var item = await AppManager.Instance.GetProfileItem(sp.IndexId);
if (item != null)
{
lst.Add(item);
}
}
if (lst.Count == 0)
{
NoticeManager.Instance.Enqueue(ResUI.PleaseSelectServer);
return null;
}
return lst;
}
public void SortServer(string colName) public void SortServer(string colName)
{ {
if (colName.IsNullOrEmpty()) if (colName.IsNullOrEmpty())

View File

@ -11,6 +11,7 @@
Width="800" Width="800"
Height="450" Height="450"
x:DataType="vms:ProfilesSelectViewModel" x:DataType="vms:ProfilesSelectViewModel"
WindowStartupLocation="CenterScreen"
mc:Ignorable="d"> mc:Ignorable="d">
<Window.Resources> <Window.Resources>
@ -27,6 +28,7 @@
<Button <Button
x:Name="btnSave" x:Name="btnSave"
Width="100" Width="100"
Click="BtnSave_Click"
Content="{x:Static resx:ResUI.TbConfirm}" /> Content="{x:Static resx:ResUI.TbConfirm}" />
<Button <Button
x:Name="btnCancel" x:Name="btnCancel"
@ -83,6 +85,9 @@
IsReadOnly="True" IsReadOnly="True"
ItemsSource="{Binding ProfileItems}" ItemsSource="{Binding ProfileItems}"
SelectionMode="Single"> SelectionMode="Single">
<DataGrid.KeyBindings>
<KeyBinding Command="{Binding SelectFinish}" Gesture="Enter" />
</DataGrid.KeyBindings>
<DataGrid.Columns> <DataGrid.Columns>
<DataGridTextColumn <DataGridTextColumn
Width="80" Width="80"
@ -90,7 +95,7 @@
Header="{x:Static resx:ResUI.LvServiceType}" Header="{x:Static resx:ResUI.LvServiceType}"
Tag="ConfigType" /> Tag="ConfigType" />
<DataGridTemplateColumn Tag="Remarks"> <DataGridTemplateColumn Tag="Remarks" SortMemberPath="Remarks">
<DataGridTemplateColumn.Header> <DataGridTemplateColumn.Header>
<TextBlock Text="{x:Static resx:ResUI.LvRemarks}" /> <TextBlock Text="{x:Static resx:ResUI.LvRemarks}" />
</DataGridTemplateColumn.Header> </DataGridTemplateColumn.Header>

View File

@ -3,9 +3,11 @@ using System.Reactive.Disposables;
using System.Threading.Tasks; using System.Threading.Tasks;
using Avalonia; using Avalonia;
using Avalonia.Controls; using Avalonia.Controls;
using Avalonia.Controls.Primitives;
using Avalonia.Input; using Avalonia.Input;
using Avalonia.Interactivity; using Avalonia.Interactivity;
using Avalonia.Markup.Xaml; using Avalonia.Markup.Xaml;
using Avalonia.VisualTree;
using Avalonia.ReactiveUI; using Avalonia.ReactiveUI;
using ReactiveUI; using ReactiveUI;
using ServiceLib.Manager; using ServiceLib.Manager;
@ -17,7 +19,9 @@ public partial class ProfilesSelectWindow : ReactiveWindow<ProfilesSelectViewMod
{ {
private static Config _config; private static Config _config;
public Task<ProfileItem?> ProfileItem => GetFirstProfileItemAsync(); public Task<ProfileItem?> ProfileItem => GetProfileItem();
public Task<List<ProfileItem>?> ProfileItems => GetProfileItems();
private bool _allowMultiSelect = false;
public ProfilesSelectWindow() public ProfilesSelectWindow()
{ {
@ -45,12 +49,12 @@ public partial class ProfilesSelectWindow : ReactiveWindow<ProfilesSelectViewMod
this.Bind(ViewModel, vm => vm.ServerFilter, v => v.txtServerFilter.Text).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); btnCancel.Click += (s, e) => Close(false);
} }
public void AllowMultiSelect(bool allow) public void AllowMultiSelect(bool allow)
{ {
_allowMultiSelect = allow;
if (allow) if (allow)
{ {
lstProfiles.SelectionMode = DataGridSelectionMode.Extended; lstProfiles.SelectionMode = DataGridSelectionMode.Extended;
@ -94,17 +98,32 @@ public partial class ProfilesSelectWindow : ReactiveWindow<ProfilesSelectViewMod
private void LstProfiles_DoubleTapped(object? sender, TappedEventArgs e) private void LstProfiles_DoubleTapped(object? sender, TappedEventArgs e)
{ {
ViewModel?.SelectFinish(); // 忽略表头区域的双击
if (e.Source is Control src)
{
if (src.FindAncestorOfType<DataGridColumnHeader>() != null)
{
e.Handled = true;
return;
} }
private async void LstProfiles_Sorting(object? sender, DataGridColumnEventArgs e) // 仅当在数据行或其子元素上双击时才触发选择
if (src.FindAncestorOfType<DataGridRow>() != null)
{ {
ViewModel?.SelectFinish();
e.Handled = true;
}
}
}
private void LstProfiles_Sorting(object? sender, DataGridColumnEventArgs e)
{
// 自定义排序,防止默认行为导致误触发
e.Handled = true; e.Handled = true;
if (ViewModel != null && e.Column?.Tag?.ToString() != null) if (ViewModel != null && e.Column?.Tag?.ToString() != null)
{ {
await ViewModel.SortServer(e.Column.Tag.ToString()); ViewModel.SortServer(e.Column.Tag.ToString());
} }
e.Handled = false;
} }
private void LstProfiles_KeyDown(object? sender, KeyEventArgs e) private void LstProfiles_KeyDown(object? sender, KeyEventArgs e)
@ -112,15 +131,20 @@ public partial class ProfilesSelectWindow : ReactiveWindow<ProfilesSelectViewMod
if (e.KeyModifiers is KeyModifiers.Control or KeyModifiers.Meta) if (e.KeyModifiers is KeyModifiers.Control or KeyModifiers.Meta)
{ {
if (e.Key == Key.A) if (e.Key == Key.A)
{
if (_allowMultiSelect)
{ {
lstProfiles.SelectAll(); lstProfiles.SelectAll();
} }
e.Handled = true;
}
} }
else else
{ {
if (e.Key is Key.Enter or Key.Return) if (e.Key is Key.Enter or Key.Return)
{ {
ViewModel?.SelectFinish(); ViewModel?.SelectFinish();
e.Handled = true;
} }
} }
} }
@ -152,9 +176,21 @@ public partial class ProfilesSelectWindow : ReactiveWindow<ProfilesSelectViewMod
} }
} }
public async Task<ProfileItem?> GetFirstProfileItemAsync() public async Task<ProfileItem?> GetProfileItem()
{ {
var item = await ViewModel?.GetProfileItem(); var item = await ViewModel?.GetProfileItem();
return item; return item;
} }
public async Task<List<ProfileItem>?> GetProfileItems()
{
var item = await ViewModel?.GetProfileItems();
return item;
}
private void BtnSave_Click(object sender, RoutedEventArgs e)
{
// Trigger selection finalize when Confirm is clicked
ViewModel?.SelectFinish();
}
} }

View File

@ -15,6 +15,7 @@
Height="450" Height="450"
x:TypeArguments="vms:ProfilesSelectViewModel" x:TypeArguments="vms:ProfilesSelectViewModel"
Style="{StaticResource WindowGlobal}" Style="{StaticResource WindowGlobal}"
WindowStartupLocation="CenterScreen"
mc:Ignorable="d"> mc:Ignorable="d">
<Window.Resources> <Window.Resources>
@ -33,6 +34,7 @@
<Button <Button
x:Name="btnSave" x:Name="btnSave"
Width="100" Width="100"
Click="BtnSave_Click"
Content="{x:Static resx:ResUI.TbConfirm}" Content="{x:Static resx:ResUI.TbConfirm}"
IsDefault="True" IsDefault="True"
Style="{StaticResource DefButton}" /> Style="{StaticResource DefButton}" />

View File

@ -15,7 +15,9 @@ public partial class ProfilesSelectWindow
{ {
private static Config _config; private static Config _config;
public Task<ProfileItem?> ProfileItem => GetFirstProfileItemAsync(); public Task<ProfileItem?> ProfileItem => GetProfileItem();
public Task<List<ProfileItem>?> ProfileItems => GetProfileItems();
private bool _allowMultiSelect = false;
public ProfilesSelectWindow() public ProfilesSelectWindow()
{ {
@ -46,6 +48,7 @@ public partial class ProfilesSelectWindow
public void AllowMultiSelect(bool allow) public void AllowMultiSelect(bool allow)
{ {
_allowMultiSelect = allow;
if (allow) if (allow)
{ {
lstProfiles.SelectionMode = DataGridSelectionMode.Extended; lstProfiles.SelectionMode = DataGridSelectionMode.Extended;
@ -108,6 +111,10 @@ public partial class ProfilesSelectWindow
private void menuSelectAll_Click(object sender, RoutedEventArgs e) private void menuSelectAll_Click(object sender, RoutedEventArgs e)
{ {
if (!_allowMultiSelect)
{
return;
}
lstProfiles.SelectAll(); lstProfiles.SelectAll();
} }
@ -119,6 +126,7 @@ public partial class ProfilesSelectWindow
{ {
case Key.A: case Key.A:
menuSelectAll_Click(null, null); menuSelectAll_Click(null, null);
e.Handled = true;
break; break;
} }
} }
@ -127,6 +135,7 @@ public partial class ProfilesSelectWindow
if (e.Key is Key.Enter or Key.Return) if (e.Key is Key.Enter or Key.Return)
{ {
ViewModel?.SelectFinish(); ViewModel?.SelectFinish();
e.Handled = true;
} }
} }
} }
@ -156,13 +165,26 @@ public partial class ProfilesSelectWindow
if (e.Key is Key.Enter or Key.Return) if (e.Key is Key.Enter or Key.Return)
{ {
ViewModel?.RefreshServers(); ViewModel?.RefreshServers();
e.Handled = true;
} }
} }
public async Task<ProfileItem?> GetFirstProfileItemAsync() public async Task<ProfileItem?> GetProfileItem()
{ {
var item = await ViewModel?.GetProfileItem(); var item = await ViewModel?.GetProfileItem();
return item; return item;
} }
public async Task<List<ProfileItem>?> GetProfileItems()
{
var item = await ViewModel?.GetProfileItems();
return item;
}
private void BtnSave_Click(object sender, RoutedEventArgs e)
{
// Trigger selection finalize when Confirm is clicked
ViewModel?.SelectFinish();
}
#endregion Event #endregion Event
} }