mirror of
https://github.com/MaaAssistantArknights/MaaAssistantArknights.git
synced 2026-07-17 18:01:26 +08:00
perf: 优化 ComboBox 搜索
This commit is contained in:
@@ -11,9 +11,13 @@
|
||||
// but WITHOUT ANY WARRANTY
|
||||
// </copyright>
|
||||
|
||||
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
|
||||
/// </summary>
|
||||
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<object>().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);
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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");
|
||||
}
|
||||
|
||||
@@ -86,6 +86,7 @@
|
||||
<controls:TooltipBlock TooltipText="{DynamicResource StartingCoreCharTip}" />
|
||||
</StackPanel>
|
||||
<hc:ComboBox
|
||||
Margin="0,0,0,15"
|
||||
Name="StartingCoreCharComboBox"
|
||||
DropDownClosed="StartingCoreCharComboBox_DropDownClosed"
|
||||
IsEditable="True"
|
||||
|
||||
Reference in New Issue
Block a user