From bcd709265e65f645f335cce36dfaa45bc47c29c4 Mon Sep 17 00:00:00 2001 From: uye <99072975+ABA2396@users.noreply.github.com> Date: Sun, 3 Aug 2025 23:54:32 +0800 Subject: [PATCH] =?UTF-8?q?perf:=20=E4=BC=98=E5=8C=96=20ComboBox=20?= =?UTF-8?q?=E6=90=9C=E7=B4=A2?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../Extensions/ComboBoxExtensions.cs | 91 +++++++++++-------- .../FightSettingsUserControlModel.cs | 7 +- .../RoguelikeSettingsUserControl.xaml | 1 + 3 files changed, 58 insertions(+), 41 deletions(-) diff --git a/src/MaaWpfGui/Extensions/ComboBoxExtensions.cs b/src/MaaWpfGui/Extensions/ComboBoxExtensions.cs index 8cd4a3fd96..5463592022 100644 --- a/src/MaaWpfGui/Extensions/ComboBoxExtensions.cs +++ b/src/MaaWpfGui/Extensions/ComboBoxExtensions.cs @@ -11,9 +11,13 @@ // but WITHOUT ANY WARRANTY // +using System; +using System.Linq; +using System.Windows; using System.Windows.Controls; using System.Windows.Input; -using MaaWpfGui.Helper; +using Serilog; +using static System.Net.Mime.MediaTypeNames; namespace MaaWpfGui.Extensions { @@ -22,6 +26,7 @@ namespace MaaWpfGui.Extensions /// public static class ComboBoxExtensions { + private static readonly ILogger _logger = Log.ForContext("SourceContext", "ComboBoxExtensions"); private const string InputTag = "TextInput"; private const string SelectionTag = "Selection"; @@ -41,71 +46,81 @@ namespace MaaWpfGui.Extensions targetComboBox.IsEditable = true; targetComboBox.IsTextSearchEnabled = false; - // enter input mode by default - targetComboBox.Tag = InputTag; + targetComboBox.Tag = SelectionTag; - targetTextBox.PreviewKeyDown += (se, ev) => + targetTextBox.PreviewKeyDown += (_, ev) => { if (ev.Key is Key.Enter or Key.Return or Key.Tab) { return; } - // switch to input mode - targetComboBox.Tag = InputTag; - - // reset selection - if (targetComboBox.SelectedItem != null) + if (targetComboBox.Tag is SelectionTag) { + var text = targetComboBox.SelectedItem?.ToString() ?? string.Empty; + _logger.Debug("Switching to input mode with text: {Text}", text); targetComboBox.SelectedItem = null; - targetComboBox.Text = string.Empty; + targetTextBox.Text = text; + targetTextBox.Select(text.Length, 0); } + // switch to input mode + targetComboBox.Tag = InputTag; targetComboBox.IsDropDownOpen = true; }; - targetTextBox.TextChanged += (o, args) => + targetTextBox.TextChanged += (_, _) => { if (targetComboBox.Tag is SelectionTag) { - // text changed in selection mode, switch to input mode - targetComboBox.Tag = InputTag; + return; + } + + var searchTerm = targetTextBox.Text; + _logger.Debug("Searching for: {SearchTerm}", searchTerm); + + // 如果文字完全匹配某个选项,恢复完整列表 + object exactMatchItem = targetComboBox.ItemsSource.Cast().FirstOrDefault(obj => obj?.ToString() == searchTerm); + + if (exactMatchItem != null) + { + targetComboBox.Items.Filter = null; + targetComboBox.SelectedItem = exactMatchItem; + targetComboBox.Dispatcher.BeginInvoke(new Action(() => + { + targetComboBox.UpdateLayout(); + if (targetComboBox.ItemContainerGenerator.ContainerFromItem(exactMatchItem) is FrameworkElement element) + { + element.BringIntoView(); + } + }), System.Windows.Threading.DispatcherPriority.Background); } else { - // input mode - var searchTerm = targetTextBox.Text; - - // reset selection - if (targetComboBox.SelectionBoxItem != null) - { - targetComboBox.SelectedItem = null; - targetTextBox.Text = searchTerm; - targetTextBox.SelectionStart = targetTextBox.Text.Length; - } - - // filter items - if (string.IsNullOrEmpty(searchTerm) || searchTerm == LocalizationHelper.GetString("NotSelected")) - { - targetComboBox.Items.Filter = item => true; - targetComboBox.SelectedItem = null; - } - else - { - targetComboBox.Items.Filter = item => item?.ToString()?.Contains(searchTerm) ?? false; - } - - targetTextBox.SelectionStart = targetTextBox.Text.Length; + targetComboBox.Items.Filter = item => item?.ToString()?.Contains(searchTerm) ?? false; } }; - targetComboBox.SelectionChanged += (o, args) => + targetComboBox.SelectionChanged += (_, _) => { - // selection changed, switch to selection mode if (targetComboBox.SelectedItem != null) { targetComboBox.Tag = SelectionTag; } + + targetComboBox.Dispatcher.BeginInvoke(new Action(() => + { + targetTextBox.Select(targetTextBox.Text.Length, 0); + }), System.Windows.Threading.DispatcherPriority.Background); + }; + + targetComboBox.DropDownOpened += (_, _) => + { + targetComboBox.Items.Filter = null; + targetComboBox.Dispatcher.BeginInvoke(new Action(() => + { + targetTextBox.Select(targetTextBox.Text.Length, 0); + }), System.Windows.Threading.DispatcherPriority.Background); }; } } diff --git a/src/MaaWpfGui/ViewModels/UserControl/TaskQueue/FightSettingsUserControlModel.cs b/src/MaaWpfGui/ViewModels/UserControl/TaskQueue/FightSettingsUserControlModel.cs index b0d8885de9..ab95b033bb 100644 --- a/src/MaaWpfGui/ViewModels/UserControl/TaskQueue/FightSettingsUserControlModel.cs +++ b/src/MaaWpfGui/ViewModels/UserControl/TaskQueue/FightSettingsUserControlModel.cs @@ -593,7 +593,7 @@ public class FightSettingsUserControlModel : TaskViewModel "3253", "3263", "3273", "3283", // 双芯片 "7001", "7002", "7003", "7004", // 许可 "4004", "4005", // 凭证 - "3105", "3131", "3132", "3233", // 龙骨/加固建材 + "3105", "3131", "3132", "3133", // 龙骨/加固建材 "6001", // 演习券 "3141", "4002", // 源石 "32001", // 芯片助剂 @@ -606,6 +606,7 @@ public class FightSettingsUserControlModel : TaskViewModel public void InitDrops() { + AllDrops.Add(new() { Display = LocalizationHelper.GetString("NotSelected"), Value = string.Empty }); foreach (var (val, value) in ItemListHelper.ArkItems) { // 不是数字的东西都是正常关卡不会掉的(大概吧) @@ -621,7 +622,7 @@ public class FightSettingsUserControlModel : TaskViewModel continue; } - AllDrops.Add(new CombinedData { Display = dis, Value = val }); + AllDrops.Add(new() { Display = dis, Value = val }); } AllDrops.Sort((a, b) => string.Compare(a.Value, b.Value, StringComparison.Ordinal)); @@ -679,7 +680,7 @@ public class FightSettingsUserControlModel : TaskViewModel DropsItemId = item.Value; - if (DropsItemName != item.Display || DropsItemId != item.Value) + if (DropsItemName != item.Display) { DropsItemName = LocalizationHelper.GetString("NotSelected"); } diff --git a/src/MaaWpfGui/Views/UserControl/TaskQueue/RoguelikeSettingsUserControl.xaml b/src/MaaWpfGui/Views/UserControl/TaskQueue/RoguelikeSettingsUserControl.xaml index a20bf3b82f..eb104c3883 100644 --- a/src/MaaWpfGui/Views/UserControl/TaskQueue/RoguelikeSettingsUserControl.xaml +++ b/src/MaaWpfGui/Views/UserControl/TaskQueue/RoguelikeSettingsUserControl.xaml @@ -86,6 +86,7 @@