improve:设置索引
This commit is contained in:
@@ -223,14 +223,14 @@
|
|||||||
</ui:SettingsCard>
|
</ui:SettingsCard>
|
||||||
|
|
||||||
<!-- 其他 -->
|
<!-- 其他 -->
|
||||||
<ui:SettingsExpander x:Name="OtherExpander"
|
<ui:SettingsCard x:Name="OtherExpander"
|
||||||
Header="{i18n:I18n Key=Storage_Other_Header}"
|
Header="{i18n:I18n Key=Storage_Other_Header}"
|
||||||
Description="{i18n:I18n Key=Storage_Other_Desc}">
|
Description="{i18n:I18n Key=Storage_Other_Desc}">
|
||||||
<ui:SettingsExpander.HeaderIcon>
|
<ui:SettingsCard.HeaderIcon>
|
||||||
<ui:FontIcon Icon="{x:Static ui:SegoeFluentIcons.More}"/>
|
<ui:FontIcon Icon="{x:Static ui:SegoeFluentIcons.More}"/>
|
||||||
</ui:SettingsExpander.HeaderIcon>
|
</ui:SettingsCard.HeaderIcon>
|
||||||
<TextBlock x:Name="OtherSizeText" Text="—" FontWeight="SemiBold" VerticalAlignment="Center"/>
|
<TextBlock x:Name="OtherSizeText" Text="—" FontWeight="SemiBold" VerticalAlignment="Center"/>
|
||||||
</ui:SettingsExpander>
|
</ui:SettingsCard>
|
||||||
|
|
||||||
<Rectangle Height="48" />
|
<Rectangle Height="48" />
|
||||||
|
|
||||||
|
|||||||
@@ -442,38 +442,180 @@ namespace Ink_Canvas.Windows.SettingsViews
|
|||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
#region 搜索框逻辑优化
|
#region 搜索框逻辑优化
|
||||||
|
|
||||||
|
private sealed class SearchEntry
|
||||||
|
{
|
||||||
|
public string Text;
|
||||||
|
public string PageTag;
|
||||||
|
public WeakReference<FrameworkElement> Target;
|
||||||
|
}
|
||||||
|
|
||||||
|
private List<SearchEntry> _searchIndex;
|
||||||
|
private bool _indexBuilt;
|
||||||
|
|
||||||
|
private void EnsureSearchIndexBuilt()
|
||||||
|
{
|
||||||
|
if (_indexBuilt && _searchIndex != null) return;
|
||||||
|
_searchIndex = new List<SearchEntry>(256);
|
||||||
|
|
||||||
|
foreach (var item in GetAllNavigationItems())
|
||||||
|
{
|
||||||
|
var text = item.Content?.ToString();
|
||||||
|
var tag = item.Tag as string;
|
||||||
|
if (!string.IsNullOrWhiteSpace(text) && !string.IsNullOrEmpty(tag))
|
||||||
|
{
|
||||||
|
_searchIndex.Add(new SearchEntry { Text = text.Trim(), PageTag = tag });
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
foreach (var kv in _pageTypes.ToList())
|
||||||
|
{
|
||||||
|
var tag = kv.Key;
|
||||||
|
if (tag == "Settings") continue;
|
||||||
|
if (kv.Value == typeof(PluginSettingsPage)) continue;
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
if (!_pages.TryGetValue(tag, out var page))
|
||||||
|
{
|
||||||
|
page = Activator.CreateInstance(kv.Value);
|
||||||
|
_pages[tag] = page;
|
||||||
|
}
|
||||||
|
if (page is FrameworkElement feRoot)
|
||||||
|
{
|
||||||
|
if (!feRoot.IsLoaded)
|
||||||
|
{
|
||||||
|
try { feRoot.ApplyTemplate(); } catch { }
|
||||||
|
}
|
||||||
|
CollectEntriesFromPage(feRoot, tag);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
System.Diagnostics.Debug.WriteLine($"为页面 {tag} 建索引失败: {ex.Message}");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
foreach (var kv in _pluginPages)
|
||||||
|
{
|
||||||
|
var pageTag = kv.Key;
|
||||||
|
var info = kv.Value;
|
||||||
|
var name = info?.Name;
|
||||||
|
if (!string.IsNullOrWhiteSpace(name))
|
||||||
|
{
|
||||||
|
_searchIndex.Add(new SearchEntry { Text = $"{name} 设置", PageTag = pageTag });
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
_indexBuilt = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void CollectEntriesFromPage(DependencyObject root, string pageTag)
|
||||||
|
{
|
||||||
|
foreach (var node in EnumerateLogicalDescendants(root))
|
||||||
|
{
|
||||||
|
string header = null;
|
||||||
|
FrameworkElement target = node as FrameworkElement;
|
||||||
|
|
||||||
|
if (node is Ink_Canvas.Controls.LabeledSettingsCard lsc)
|
||||||
|
{
|
||||||
|
header = lsc.Header;
|
||||||
|
}
|
||||||
|
else if (node is iNKORE.UI.WPF.Modern.Controls.SettingsCard sc)
|
||||||
|
{
|
||||||
|
header = sc.Header?.ToString();
|
||||||
|
}
|
||||||
|
else if (node is iNKORE.UI.WPF.Modern.Controls.SettingsExpander se)
|
||||||
|
{
|
||||||
|
header = se.Header?.ToString();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!string.IsNullOrWhiteSpace(header) && target != null)
|
||||||
|
{
|
||||||
|
_searchIndex.Add(new SearchEntry
|
||||||
|
{
|
||||||
|
Text = header.Trim(),
|
||||||
|
PageTag = pageTag,
|
||||||
|
Target = new WeakReference<FrameworkElement>(target)
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static IEnumerable<DependencyObject> EnumerateLogicalDescendants(DependencyObject root)
|
||||||
|
{
|
||||||
|
if (root == null) yield break;
|
||||||
|
var stack = new Stack<DependencyObject>();
|
||||||
|
stack.Push(root);
|
||||||
|
while (stack.Count > 0)
|
||||||
|
{
|
||||||
|
var node = stack.Pop();
|
||||||
|
yield return node;
|
||||||
|
foreach (var child in LogicalTreeHelper.GetChildren(node))
|
||||||
|
{
|
||||||
|
if (child is DependencyObject d) stack.Push(d);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void NavigateToSearchEntry(SearchEntry entry)
|
||||||
|
{
|
||||||
|
if (entry == null) return;
|
||||||
|
|
||||||
|
NavigateToPage(entry.PageTag);
|
||||||
|
var navItem = FindNavigationViewItemByTag(entry.PageTag);
|
||||||
|
if (navItem != null && NavigationViewControl.SelectedItem != navItem)
|
||||||
|
{
|
||||||
|
NavigationViewControl.SelectedItem = navItem;
|
||||||
|
NavigationViewControl.Header = navItem.Content;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (entry.Target != null && entry.Target.TryGetTarget(out var fe))
|
||||||
|
{
|
||||||
|
Dispatcher.BeginInvoke(new Action(() =>
|
||||||
|
{
|
||||||
|
try { fe.BringIntoView(); } catch { }
|
||||||
|
}), System.Windows.Threading.DispatcherPriority.Background);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private void OnControlsSearchBoxQuerySubmitted(AutoSuggestBox sender, AutoSuggestBoxQuerySubmittedEventArgs args)
|
private void OnControlsSearchBoxQuerySubmitted(AutoSuggestBox sender, AutoSuggestBoxQuerySubmittedEventArgs args)
|
||||||
{
|
{
|
||||||
if (string.IsNullOrWhiteSpace(args.QueryText)) return;
|
EnsureSearchIndexBuilt();
|
||||||
|
|
||||||
string query = args.QueryText.Trim().ToLower();
|
string raw = (args.ChosenSuggestion as string) ?? args.QueryText;
|
||||||
var allNavItems = GetAllNavigationItems();
|
if (string.IsNullOrWhiteSpace(raw)) return;
|
||||||
|
|
||||||
var targetItem = allNavItems.FirstOrDefault(item =>
|
string query = raw.Trim();
|
||||||
item.Content?.ToString().ToLower().Contains(query) == true);
|
string queryLower = query.ToLower();
|
||||||
|
|
||||||
if (targetItem != null)
|
var entry = _searchIndex.FirstOrDefault(e => e.Text.Equals(query, StringComparison.OrdinalIgnoreCase))
|
||||||
{
|
?? _searchIndex.FirstOrDefault(e => e.Text.ToLower().Contains(queryLower));
|
||||||
NavigationViewControl.SelectedItem = targetItem;
|
|
||||||
}
|
NavigateToSearchEntry(entry);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void OnControlsSearchBoxTextChanged(AutoSuggestBox sender, AutoSuggestBoxTextChangedEventArgs args)
|
private void OnControlsSearchBoxTextChanged(AutoSuggestBox sender, AutoSuggestBoxTextChangedEventArgs args)
|
||||||
{
|
{
|
||||||
if (args.Reason != AutoSuggestionBoxTextChangeReason.UserInput) return;
|
if (args.Reason != AutoSuggestionBoxTextChangeReason.UserInput) return;
|
||||||
|
|
||||||
string query = sender.Text.Trim().ToLower();
|
EnsureSearchIndexBuilt();
|
||||||
var suggestions = new List<string>();
|
|
||||||
|
|
||||||
if (!string.IsNullOrEmpty(query))
|
string query = sender.Text?.Trim() ?? string.Empty;
|
||||||
|
if (string.IsNullOrEmpty(query))
|
||||||
{
|
{
|
||||||
var allNavItems = GetAllNavigationItems();
|
sender.ItemsSource = null;
|
||||||
suggestions = allNavItems
|
return;
|
||||||
.Where(item => item.Content?.ToString().ToLower().Contains(query) == true)
|
|
||||||
.Select(item => item.Content.ToString())
|
|
||||||
.ToList();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
string queryLower = query.ToLower();
|
||||||
|
var suggestions = _searchIndex
|
||||||
|
.Where(e => e.Text.ToLower().Contains(queryLower))
|
||||||
|
.Select(e => e.Text)
|
||||||
|
.Distinct()
|
||||||
|
.Take(50)
|
||||||
|
.ToList();
|
||||||
|
|
||||||
sender.ItemsSource = suggestions;
|
sender.ItemsSource = suggestions;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user