From 3d4e1872f10563d06c93165bfe9378a44da91c2c Mon Sep 17 00:00:00 2001
From: CJKmkp <2564608840@qq.com>
Date: Sun, 28 Dec 2025 10:40:13 +0800
Subject: [PATCH] =?UTF-8?q?add:=E6=96=B0=E8=AE=BE=E7=BD=AE?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
增加搜索功能
---
Ink Canvas/InkCanvasForClass.csproj | 1 +
.../SettingsViews/SearchPanel.xaml | 140 ++++++
.../SettingsViews/SearchPanel.xaml.cs | 418 ++++++++++++++++++
.../Windows/SettingsViews/SettingsWindow.xaml | 5 +
.../SettingsViews/SettingsWindow.xaml.cs | 42 +-
5 files changed, 605 insertions(+), 1 deletion(-)
create mode 100644 Ink Canvas/Windows/SettingsViews/SettingsViews/SearchPanel.xaml
create mode 100644 Ink Canvas/Windows/SettingsViews/SettingsViews/SearchPanel.xaml.cs
diff --git a/Ink Canvas/InkCanvasForClass.csproj b/Ink Canvas/InkCanvasForClass.csproj
index 4d5ed9d1..3cb49b7e 100644
--- a/Ink Canvas/InkCanvasForClass.csproj
+++ b/Ink Canvas/InkCanvasForClass.csproj
@@ -154,6 +154,7 @@
+
diff --git a/Ink Canvas/Windows/SettingsViews/SettingsViews/SearchPanel.xaml b/Ink Canvas/Windows/SettingsViews/SettingsViews/SearchPanel.xaml
new file mode 100644
index 00000000..d36e7f85
--- /dev/null
+++ b/Ink Canvas/Windows/SettingsViews/SettingsViews/SearchPanel.xaml
@@ -0,0 +1,140 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/Ink Canvas/Windows/SettingsViews/SettingsViews/SearchPanel.xaml.cs b/Ink Canvas/Windows/SettingsViews/SettingsViews/SearchPanel.xaml.cs
new file mode 100644
index 00000000..bb551de6
--- /dev/null
+++ b/Ink Canvas/Windows/SettingsViews/SettingsViews/SearchPanel.xaml.cs
@@ -0,0 +1,418 @@
+using System;
+using System.Collections.Generic;
+using System.Collections.ObjectModel;
+using System.Globalization;
+using System.Linq;
+using System.Text;
+using System.Text.RegularExpressions;
+using System.Windows;
+using System.Windows.Controls;
+using System.Windows.Input;
+using System.Windows.Media;
+using Microsoft.International.Converters.PinYinConverter;
+
+namespace Ink_Canvas.Windows.SettingsViews
+{
+ ///
+ /// SearchPanel.xaml 的交互逻辑
+ ///
+ public partial class SearchPanel : UserControl
+ {
+ public event EventHandler NavigateToItem;
+ public event EventHandler CloseSearch;
+
+ private ObservableCollection _exactMatches = new ObservableCollection();
+ private ObservableCollection _fuzzyMatches = new ObservableCollection();
+ private ObservableCollection _relatedItems = new ObservableCollection();
+
+ private List _allSettings = new List();
+
+ public SearchPanel()
+ {
+ InitializeComponent();
+ InitializeSettings();
+ ExactMatchItemsControl.ItemsSource = _exactMatches;
+ FuzzyMatchItemsControl.ItemsSource = _fuzzyMatches;
+ RelatedItemsControl.ItemsSource = _relatedItems;
+ }
+
+ private void InitializeSettings()
+ {
+ // 初始化所有设置项数据
+ _allSettings = new List
+ {
+ // 启动时行为
+ new SettingItem { Title = "启动时行为", Category = "启动时行为", ItemName = "StartupItem", Type = SettingItemType.Category },
+
+ // 画板和墨迹
+ new SettingItem { Title = "画板和墨迹", Category = "画板和墨迹", ItemName = "CanvasAndInkItem", Type = SettingItemType.Category },
+
+ // 手势操作
+ new SettingItem { Title = "手势操作", Category = "手势操作", ItemName = "GesturesItem", Type = SettingItemType.Category },
+
+ // 墨迹纠正
+ new SettingItem { Title = "墨迹纠正", Category = "墨迹纠正", ItemName = "InkRecognitionItem", Type = SettingItemType.Category },
+
+ // 个性化设置
+ new SettingItem { Title = "个性化设置", Category = "个性化设置", ItemName = "ThemeItem", Type = SettingItemType.Category },
+
+ // 快捷键设置
+ new SettingItem { Title = "快捷键设置", Category = "快捷键设置", ItemName = "ShortcutsItem", Type = SettingItemType.Category },
+
+ // 崩溃处理
+ new SettingItem { Title = "崩溃处理", Category = "崩溃处理", ItemName = "CrashActionItem", Type = SettingItemType.Category },
+
+ // PowerPoint 支持
+ new SettingItem { Title = "PowerPoint 支持", Category = "PowerPoint 支持", ItemName = "PowerPointItem", Type = SettingItemType.Category },
+
+ // 自动化行为
+ new SettingItem { Title = "自动化行为", Category = "自动化行为", ItemName = "AutomationItem", Type = SettingItemType.Category },
+
+ // 随机点名
+ new SettingItem { Title = "随机点名", Category = "随机点名", ItemName = "LuckyRandomItem", Type = SettingItemType.Category },
+
+ // 存储空间
+ new SettingItem { Title = "存储空间", Category = "存储空间", ItemName = "StorageItem", Type = SettingItemType.Category },
+
+ // 截图和屏幕捕捉
+ new SettingItem { Title = "截图和屏幕捕捉", Category = "截图和屏幕捕捉", ItemName = "SnapshotItem", Type = SettingItemType.Category },
+
+ // 高级选项
+ new SettingItem { Title = "高级选项", Category = "高级选项", ItemName = "AdvancedItem", Type = SettingItemType.Category },
+
+ // 关于
+ new SettingItem { Title = "关于 InkCanvasForClass", Category = "关于", ItemName = "AboutItem", Type = SettingItemType.Category },
+ };
+ }
+
+ public void PerformSearch(string searchText)
+ {
+ if (string.IsNullOrWhiteSpace(searchText))
+ {
+ ClearResults();
+ return;
+ }
+
+ _exactMatches.Clear();
+ _fuzzyMatches.Clear();
+ _relatedItems.Clear();
+
+ var searchLower = searchText.ToLower();
+ var exactMatchSet = new HashSet();
+ var fuzzyMatchSet = new HashSet();
+
+ // 精准匹配和拼音匹配
+ foreach (var setting in _allSettings)
+ {
+ var titleLower = setting.Title.ToLower();
+ var categoryLower = setting.Category.ToLower();
+
+ // 精准匹配
+ if (titleLower.Contains(searchLower) || categoryLower.Contains(searchLower))
+ {
+ if (!exactMatchSet.Contains(setting.ItemName))
+ {
+ _exactMatches.Add(new SearchResultItem
+ {
+ Title = setting.Title,
+ Category = setting.Category,
+ ItemName = setting.ItemName,
+ Type = setting.Type,
+ MatchType = MatchType.Exact
+ });
+ exactMatchSet.Add(setting.ItemName);
+ }
+ }
+ // 拼音匹配
+ else if (ContainsPinyinMatch(setting.Title, searchText) || ContainsPinyinMatch(setting.Category, searchText))
+ {
+ if (!exactMatchSet.Contains(setting.ItemName))
+ {
+ _exactMatches.Add(new SearchResultItem
+ {
+ Title = setting.Title,
+ Category = setting.Category,
+ ItemName = setting.ItemName,
+ Type = setting.Type,
+ MatchType = MatchType.Pinyin
+ });
+ exactMatchSet.Add(setting.ItemName);
+ }
+ }
+ }
+
+ // 模糊匹配
+ foreach (var setting in _allSettings)
+ {
+ if (exactMatchSet.Contains(setting.ItemName))
+ continue;
+
+ var searchableText = $"{setting.Title} {setting.Category} {setting.Description}".ToLower();
+ if (FuzzyMatch(searchableText, searchLower))
+ {
+ if (!fuzzyMatchSet.Contains(setting.ItemName))
+ {
+ _fuzzyMatches.Add(new SearchResultItem
+ {
+ Title = setting.Title,
+ Category = setting.Category,
+ ItemName = setting.ItemName,
+ Type = setting.Type,
+ MatchType = MatchType.Fuzzy
+ });
+ fuzzyMatchSet.Add(setting.ItemName);
+ }
+ }
+ }
+
+ // 相关项
+ var allMatched = new HashSet(exactMatchSet.Concat(fuzzyMatchSet));
+ foreach (var setting in _allSettings)
+ {
+ if (!allMatched.Contains(setting.ItemName))
+ {
+ // 简单的相关性判断
+ if (IsRelated(setting, searchText))
+ {
+ _relatedItems.Add(new SearchResultItem
+ {
+ Title = setting.Title,
+ Category = setting.Category,
+ ItemName = setting.ItemName,
+ Type = setting.Type,
+ MatchType = MatchType.Related
+ });
+ }
+ }
+ }
+
+ UpdateResultsVisibility();
+ }
+
+ private bool ContainsPinyinMatch(string text, string search)
+ {
+ if (string.IsNullOrWhiteSpace(text) || string.IsNullOrWhiteSpace(search))
+ return false;
+
+ try
+ {
+ // 将搜索词转换为小写
+ var searchLower = search.ToLower();
+
+ // 获取文本的拼音首字母和全拼
+ var pinyinInitials = GetPinyinInitials(text);
+ var pinyinFull = GetPinyinFull(text);
+
+ // 检查搜索词是否匹配拼音首字母或全拼
+ if (pinyinInitials.ToLower().Contains(searchLower) ||
+ pinyinFull.ToLower().Contains(searchLower))
+ {
+ return true;
+ }
+ }
+ catch
+ {
+ // 如果拼音转换失败,返回false
+ return false;
+ }
+
+ return false;
+ }
+
+ private string GetPinyinInitials(string text)
+ {
+ var sb = new StringBuilder();
+ foreach (char c in text)
+ {
+ if (IsChinese(c))
+ {
+ try
+ {
+ var chineseChar = new ChineseChar(c);
+ if (chineseChar.PinyinCount > 0)
+ {
+ var pinyin = chineseChar.Pinyins[0];
+ if (!string.IsNullOrEmpty(pinyin) && pinyin.Length > 0)
+ {
+ // 获取首字母(移除音调数字后取第一个字母)
+ var firstChar = Regex.Replace(pinyin, @"\d", "")[0];
+ sb.Append(firstChar);
+ }
+ }
+ }
+ catch
+ {
+ sb.Append(c);
+ }
+ }
+ else
+ {
+ sb.Append(c);
+ }
+ }
+ return sb.ToString();
+ }
+
+ private string GetPinyinFull(string text)
+ {
+ var sb = new StringBuilder();
+ foreach (char c in text)
+ {
+ if (IsChinese(c))
+ {
+ try
+ {
+ var chineseChar = new ChineseChar(c);
+ if (chineseChar.PinyinCount > 0)
+ {
+ var pinyin = chineseChar.Pinyins[0];
+ // 移除音调数字
+ pinyin = Regex.Replace(pinyin, @"\d", "");
+ sb.Append(pinyin);
+ }
+ }
+ catch
+ {
+ sb.Append(c);
+ }
+ }
+ else
+ {
+ sb.Append(c);
+ }
+ }
+ return sb.ToString();
+ }
+
+ private bool IsChinese(char c)
+ {
+ return c >= 0x4e00 && c <= 0x9fbb;
+ }
+
+ private bool FuzzyMatch(string text, string search)
+ {
+ if (string.IsNullOrWhiteSpace(text) || string.IsNullOrWhiteSpace(search))
+ return false;
+
+ // 简单的模糊匹配:检查搜索词的字符是否按顺序出现在文本中
+ int searchIndex = 0;
+ foreach (char c in text)
+ {
+ if (searchIndex < search.Length && c == search[searchIndex])
+ {
+ searchIndex++;
+ if (searchIndex == search.Length)
+ return true;
+ }
+ }
+ return false;
+ }
+
+ private bool IsRelated(SettingItem setting, string search)
+ {
+ // 简单的相关性判断,可以根据需要改进
+ // 例如:检查是否有共同的关键词等
+ return false; // 暂时禁用相关项功能
+ }
+
+ private void UpdateResultsVisibility()
+ {
+ ExactMatchPanel.Visibility = _exactMatches.Count > 0 ? Visibility.Visible : Visibility.Collapsed;
+ FuzzyMatchPanel.Visibility = _fuzzyMatches.Count > 0 ? Visibility.Visible : Visibility.Collapsed;
+ RelatedItemsPanel.Visibility = _relatedItems.Count > 0 ? Visibility.Visible : Visibility.Collapsed;
+
+ bool hasResults = _exactMatches.Count > 0 || _fuzzyMatches.Count > 0 || _relatedItems.Count > 0;
+ NoResultsText.Visibility = hasResults ? Visibility.Collapsed : Visibility.Visible;
+ }
+
+ private void ClearResults()
+ {
+ _exactMatches.Clear();
+ _fuzzyMatches.Clear();
+ _relatedItems.Clear();
+ UpdateResultsVisibility();
+ }
+
+ private void SearchTextBox_KeyDown(object sender, KeyEventArgs e)
+ {
+ if (e.Key == Key.Escape)
+ {
+ CloseSearch?.Invoke(this, EventArgs.Empty);
+ }
+ }
+
+ private void SearchTextBox_TextChanged(object sender, TextChangedEventArgs e)
+ {
+ var textBox = sender as TextBox;
+ if (textBox != null)
+ {
+ PerformSearch(textBox.Text);
+ }
+ }
+
+ private void SearchTextBox_GotFocus(object sender, RoutedEventArgs e)
+ {
+ var textBox = sender as TextBox;
+ textBox?.SelectAll();
+ }
+
+ private void CloseSearchButton_Click(object sender, MouseButtonEventArgs e)
+ {
+ CloseSearch?.Invoke(this, EventArgs.Empty);
+ }
+
+ private void SearchResultItem_Click(object sender, MouseButtonEventArgs e)
+ {
+ var border = sender as Border;
+ if (border?.Tag is SearchResultItem item)
+ {
+ NavigateToItem?.Invoke(this, item.ItemName);
+ }
+ }
+
+ public void FocusSearchBox()
+ {
+ SearchTextBox.Focus();
+ }
+
+ public void SetSearchText(string text)
+ {
+ SearchTextBox.Text = text;
+ PerformSearch(text);
+ }
+ }
+
+ public class SettingItem
+ {
+ public string Title { get; set; }
+ public string Category { get; set; }
+ public string ItemName { get; set; }
+ public string Description { get; set; } = "";
+ public SettingItemType Type { get; set; }
+ }
+
+ public class SearchResultItem
+ {
+ public string Title { get; set; }
+ public string Category { get; set; }
+ public string ItemName { get; set; }
+ public SettingItemType Type { get; set; }
+ public MatchType MatchType { get; set; }
+ public string Description { get; set; } = "";
+ }
+
+ public enum SettingItemType
+ {
+ Category,
+ Setting
+ }
+
+ public enum MatchType
+ {
+ Exact,
+ Pinyin,
+ Fuzzy,
+ Related
+ }
+}
+
diff --git a/Ink Canvas/Windows/SettingsViews/SettingsWindow.xaml b/Ink Canvas/Windows/SettingsViews/SettingsWindow.xaml
index 08a33133..1a6aba6b 100644
--- a/Ink Canvas/Windows/SettingsViews/SettingsWindow.xaml
+++ b/Ink Canvas/Windows/SettingsViews/SettingsWindow.xaml
@@ -622,6 +622,11 @@
+
+
+
+
+
diff --git a/Ink Canvas/Windows/SettingsViews/SettingsWindow.xaml.cs b/Ink Canvas/Windows/SettingsViews/SettingsWindow.xaml.cs
index b6a99a59..514bf164 100644
--- a/Ink Canvas/Windows/SettingsViews/SettingsWindow.xaml.cs
+++ b/Ink Canvas/Windows/SettingsViews/SettingsWindow.xaml.cs
@@ -18,6 +18,10 @@ namespace Ink_Canvas.Windows
public SettingsWindow()
{
InitializeComponent();
+
+ // 初始化搜索面板事件
+ SearchPanelControl.NavigateToItem += SearchPanel_NavigateToItem;
+ SearchPanelControl.CloseSearch += SearchPanel_CloseSearch;
// 初始化侧边栏项目
SidebarItemsControl.ItemsSource = SidebarItems;
@@ -445,7 +449,43 @@ namespace Ink_Canvas.Windows
private void SearchButton_Click(object sender, MouseButtonEventArgs e)
{
- // 搜索功能 - 可以显示搜索框或搜索对话框
+ // 显示搜索界面
+ SearchPane.Visibility = Visibility.Visible;
+ SearchPanelControl.FocusSearchBox();
+ }
+
+ private void SearchPanel_NavigateToItem(object sender, string itemName)
+ {
+ // 隐藏搜索界面
+ SearchPane.Visibility = Visibility.Collapsed;
+
+ // 导航到对应的设置项
+ NavigateToSidebarItem(itemName);
+ }
+
+ private void SearchPanel_CloseSearch(object sender, EventArgs e)
+ {
+ // 隐藏搜索界面
+ SearchPane.Visibility = Visibility.Collapsed;
+ }
+
+ private void NavigateToSidebarItem(string itemName)
+ {
+ // 查找对应的侧边栏项并选中
+ foreach (var item in SidebarItems)
+ {
+ if (item.Name == itemName)
+ {
+ SelectSidebarItem(item);
+ break;
+ }
+ }
+ }
+
+ private void SelectSidebarItem(SidebarItem item)
+ {
+ _selectedSidebarItemName = item.Name;
+ UpdateSidebarItemsSelection();
}
private void MenuButton_Click(object sender, MouseButtonEventArgs e)