add:高dpi适配 插件接口 设置窗口多显示器优化 fix:触摸后鼠标指针显示异常
This commit is contained in:
@@ -111,6 +111,7 @@
|
||||
<Reference Include="Microsoft.VisualBasic" />
|
||||
<Reference Include="netstandard" />
|
||||
<Reference Include="System.Windows.Forms" />
|
||||
<Reference Include="System.ComponentModel.Composition" />
|
||||
<Reference Include="Microsoft.CSharp" />
|
||||
<Reference Include="System.Data.DataSetExtensions" />
|
||||
<Reference Include="System.Management" />
|
||||
|
||||
@@ -8,6 +8,7 @@
|
||||
xmlns:ikw="http://schemas.inkore.net/lib/ui/wpf"
|
||||
Title="InkCanvasForClass 设置"
|
||||
Width="1138" Height="750"
|
||||
MinWidth="800" MinHeight="600"
|
||||
WindowStartupLocation="CenterScreen"
|
||||
ui:ThemeManager.IsThemeAware="True"
|
||||
ui:TitleBar.ExtendViewIntoTitleBar="True"
|
||||
@@ -15,6 +16,7 @@
|
||||
ui:WindowHelper.UseModernWindowStyle="True"
|
||||
ui:TitleBar.Height="48"
|
||||
mc:Ignorable="d">
|
||||
|
||||
<Window.Resources>
|
||||
<ResourceDictionary>
|
||||
<ResourceDictionary.MergedDictionaries>
|
||||
@@ -22,6 +24,7 @@
|
||||
</ResourceDictionary.MergedDictionaries>
|
||||
</ResourceDictionary>
|
||||
</Window.Resources>
|
||||
|
||||
<Grid>
|
||||
<ui:NavigationView
|
||||
x:Name="NavigationViewControl"
|
||||
@@ -38,34 +41,39 @@
|
||||
IsBackButtonVisible="Visible"
|
||||
IsBackEnabled="True"
|
||||
PaneDisplayMode="Auto"
|
||||
ScrollViewer.VerticalScrollBarVisibility="Hidden"
|
||||
OpenPaneLength="240"
|
||||
ScrollViewer.VerticalScrollBarVisibility="Auto"
|
||||
ScrollViewer.HorizontalScrollBarVisibility="Disabled">
|
||||
|
||||
<ui:NavigationView.HeaderTemplate>
|
||||
<DataTemplate>
|
||||
<Grid>
|
||||
<Grid Margin="0,8,0,12">
|
||||
<TextBlock
|
||||
Text="{Binding}"
|
||||
Style="{DynamicResource TitleTextBlockStyle}"
|
||||
Margin="0,8,0,0" />
|
||||
FontSize="20"
|
||||
FontWeight="SemiBold"/>
|
||||
</Grid>
|
||||
</DataTemplate>
|
||||
</ui:NavigationView.HeaderTemplate>
|
||||
|
||||
<ui:NavigationView.AutoSuggestBox>
|
||||
<ui:AutoSuggestBox
|
||||
x:Name="controlsSearchBox"
|
||||
MinWidth="200"
|
||||
MinWidth="220"
|
||||
VerticalAlignment="Center"
|
||||
x:FieldModifier="public"
|
||||
PlaceholderText="查找设置"
|
||||
QuerySubmitted="OnControlsSearchBoxQuerySubmitted"
|
||||
TextChanged="OnControlsSearchBoxTextChanged" >
|
||||
TextChanged="OnControlsSearchBoxTextChanged">
|
||||
<ui:AutoSuggestBox.QueryIcon>
|
||||
<ui:SymbolIcon Symbol="Find" FontSize="12" />
|
||||
<ui:FontIcon Icon="{x:Static ui:SegoeFluentIcons.Search}" FontSize="12"/>
|
||||
</ui:AutoSuggestBox.QueryIcon>
|
||||
</ui:AutoSuggestBox>
|
||||
</ui:NavigationView.AutoSuggestBox>
|
||||
|
||||
<ui:NavigationView.MenuItems>
|
||||
<!-- 基本设置 -->
|
||||
<ui:NavigationViewItem
|
||||
x:Name="BasicItem"
|
||||
Content="基本"
|
||||
@@ -87,6 +95,8 @@
|
||||
</ui:NavigationViewItem>
|
||||
</ui:NavigationViewItem.MenuItems>
|
||||
</ui:NavigationViewItem>
|
||||
|
||||
<!-- 页面2 -->
|
||||
<ui:NavigationViewItem
|
||||
x:Name="Page2Item"
|
||||
Content="页面 2"
|
||||
@@ -95,6 +105,8 @@
|
||||
<ui:SymbolIcon Symbol="Document" />
|
||||
</ui:NavigationViewItem.Icon>
|
||||
</ui:NavigationViewItem>
|
||||
|
||||
<!-- 设计设置 -->
|
||||
<ui:NavigationViewItem
|
||||
x:Name="DesignItem"
|
||||
Content="设计"
|
||||
@@ -107,21 +119,25 @@
|
||||
<ui:NavigationViewItem
|
||||
x:Name="IconographyItem"
|
||||
Content="图标"
|
||||
Tag="Iconography">
|
||||
Tag="Iconography"
|
||||
ToolTipService.ToolTip="图标设置">
|
||||
<ui:NavigationViewItem.Icon>
|
||||
<ui:SymbolIcon Symbol="Home" />
|
||||
<ui:FontIcon Icon="{x:Static ui:SegoeFluentIcons.AllApps}"/>
|
||||
</ui:NavigationViewItem.Icon>
|
||||
</ui:NavigationViewItem>
|
||||
<ui:NavigationViewItem
|
||||
x:Name="TypographyItem"
|
||||
Content="排版"
|
||||
Tag="Typography">
|
||||
Tag="Typography"
|
||||
ToolTipService.ToolTip="排版设置">
|
||||
<ui:NavigationViewItem.Icon>
|
||||
<ui:SymbolIcon Symbol="Home" />
|
||||
<ui:FontIcon Icon="{x:Static ui:SegoeFluentIcons.Font}"/>
|
||||
</ui:NavigationViewItem.Icon>
|
||||
</ui:NavigationViewItem>
|
||||
</ui:NavigationViewItem.MenuItems>
|
||||
</ui:NavigationViewItem>
|
||||
|
||||
<!-- 外观设置 -->
|
||||
<ui:NavigationViewItem
|
||||
x:Name="AppearanceItem"
|
||||
Content="外观"
|
||||
@@ -134,25 +150,28 @@
|
||||
<ui:NavigationViewItem
|
||||
x:Name="ThemeItem"
|
||||
Content="主题"
|
||||
Tag="Theme">
|
||||
Tag="Theme"
|
||||
ToolTipService.ToolTip="主题设置">
|
||||
<ui:NavigationViewItem.Icon>
|
||||
<ui:SymbolIcon Symbol="Home" />
|
||||
<ui:FontIcon Icon="{x:Static ui:FluentSystemIcons.DarkTheme_24_Regular}"/>
|
||||
</ui:NavigationViewItem.Icon>
|
||||
</ui:NavigationViewItem>
|
||||
<ui:NavigationViewItem
|
||||
x:Name="ColorsItem"
|
||||
Content="颜色"
|
||||
Tag="Colors">
|
||||
Tag="Colors"
|
||||
ToolTipService.ToolTip="颜色设置">
|
||||
<ui:NavigationViewItem.Icon>
|
||||
<ui:SymbolIcon Symbol="Home" />
|
||||
<ui:FontIcon Icon="{x:Static ui:SegoeFluentIcons.Highlight}"/>
|
||||
</ui:NavigationViewItem.Icon>
|
||||
</ui:NavigationViewItem>
|
||||
<ui:NavigationViewItem
|
||||
x:Name="FontsItem"
|
||||
Content="字体"
|
||||
Tag="Fonts">
|
||||
Tag="Fonts"
|
||||
ToolTipService.ToolTip="字体设置">
|
||||
<ui:NavigationViewItem.Icon>
|
||||
<ui:SymbolIcon Symbol="Home" />
|
||||
<ui:FontIcon Icon="{x:Static ui:SegoeFluentIcons.Font}"/>
|
||||
</ui:NavigationViewItem.Icon>
|
||||
</ui:NavigationViewItem>
|
||||
</ui:NavigationViewItem.MenuItems>
|
||||
@@ -170,7 +189,7 @@
|
||||
</ui:NavigationViewItem>
|
||||
</ui:NavigationView.FooterMenuItems>
|
||||
|
||||
<ui:Frame x:Name="rootFrame" Navigated="OnRootFrameNavigated" />
|
||||
<ui:Frame x:Name="rootFrame" Navigated="OnRootFrameNavigated" NavigationUIVisibility="Hidden" />
|
||||
</ui:NavigationView>
|
||||
</Grid>
|
||||
</Window>
|
||||
|
||||
@@ -4,20 +4,39 @@ using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Windows;
|
||||
using System.Windows.Navigation;
|
||||
using System.Windows.Forms;
|
||||
using System.Windows.Interop;
|
||||
using System.Windows.Input;
|
||||
using System.ComponentModel.Composition;
|
||||
using System.ComponentModel.Composition.Hosting;
|
||||
using System.Linq;
|
||||
using MessageBox = System.Windows.MessageBox;
|
||||
using Screen = System.Windows.Forms.Screen;
|
||||
|
||||
namespace Ink_Canvas.Windows.SettingsViews2
|
||||
{
|
||||
// 插件设置页面契约接口,所有插件必须实现此接口即可自动接入
|
||||
public interface IPluginSettingsPage
|
||||
{
|
||||
string PageTag { get; } // 页面唯一标识,不可与内置页面重复
|
||||
string PageTitle { get; } // 导航菜单显示的标题
|
||||
string PageIconCode { get; } // Segoe MDL2 Assets 图标字符,例:"\xE713"(设置图标)
|
||||
Type PageType { get; } // 插件设置页面的类型(继承自Page)
|
||||
bool IsFooterItem { get; } // 是否放在导航底部菜单
|
||||
}
|
||||
|
||||
public partial class SettingsWindow2 : Window
|
||||
{
|
||||
private Dictionary<string, Type> _pageTypes;
|
||||
private Dictionary<string, object> _pages = new Dictionary<string, object>();
|
||||
private readonly Dictionary<string, Type> _pageTypes;
|
||||
private readonly Dictionary<string, object> _pages = new Dictionary<string, object>();
|
||||
|
||||
[ImportMany(typeof(IPluginSettingsPage))]
|
||||
private IEnumerable<IPluginSettingsPage> _pluginPages; // 自动导入所有插件页面
|
||||
|
||||
public SettingsWindow2()
|
||||
{
|
||||
InitializeComponent();
|
||||
|
||||
// 初始化页面类型映射
|
||||
// 初始化内置页面映射
|
||||
_pageTypes = new Dictionary<string, Type>
|
||||
{
|
||||
{ "Basic", typeof(Basic) },
|
||||
@@ -34,157 +53,260 @@ namespace Ink_Canvas.Windows.SettingsViews2
|
||||
{ "Settings", typeof(SettingsPage) }
|
||||
};
|
||||
|
||||
// 默认选中第一个项目
|
||||
// 加载插件页面
|
||||
LoadPluginSettingsPages();
|
||||
// 初始化导航菜单(内置+插件)
|
||||
InitializeNavigationMenu();
|
||||
|
||||
// 默认选中第一个菜单项
|
||||
if (NavigationViewControl.MenuItems.Count > 0)
|
||||
{
|
||||
NavigationViewControl.SelectedItem = NavigationViewControl.MenuItems[0];
|
||||
}
|
||||
|
||||
// 窗口加载完成后设置最大尺寸,确保能正确获取 DPI 缩放因子
|
||||
// 窗口生命周期事件注册
|
||||
this.Loaded += (sender, e) =>
|
||||
{
|
||||
SetMaxWindowSize();
|
||||
SetMaxSizeAndCenter();
|
||||
RegisterDpiChangedListener();
|
||||
};
|
||||
|
||||
// 窗口拖动到其他屏幕时自动适配
|
||||
this.LocationChanged += (sender, e) =>
|
||||
{
|
||||
SetMaxSizeAndCenter();
|
||||
};
|
||||
|
||||
// 窗口关闭时释放资源
|
||||
this.Closed += (sender, e) =>
|
||||
{
|
||||
UnregisterDpiChangedListener();
|
||||
_pages.Clear();
|
||||
_pageTypes.Clear();
|
||||
};
|
||||
|
||||
// 修复触摸屏操作后鼠标指针消失的问题
|
||||
FixTouchScreenCursorIssue();
|
||||
}
|
||||
|
||||
#region 修复触摸屏鼠标指针消失问题
|
||||
private void FixTouchScreenCursorIssue()
|
||||
{
|
||||
// 触摸结束时强制显示鼠标指针
|
||||
this.TouchUp += (s, e) =>
|
||||
{
|
||||
ShowCursor(true);
|
||||
};
|
||||
|
||||
// 鼠标进入窗口时确保指针可见
|
||||
this.MouseEnter += (s, e) =>
|
||||
{
|
||||
ShowCursor(true);
|
||||
};
|
||||
|
||||
// 窗口激活时确保指针可见
|
||||
this.Activated += (s, e) =>
|
||||
{
|
||||
ShowCursor(true);
|
||||
};
|
||||
}
|
||||
|
||||
private void SetMaxWindowSize()
|
||||
{
|
||||
// 设置最大高度和宽度为工作区的高度和宽度,分别减去 40 和 10,并考虑 DPI 缩放
|
||||
var workingArea = System.Windows.Forms.Screen.PrimaryScreen.WorkingArea;
|
||||
[System.Runtime.InteropServices.DllImport("user32.dll")]
|
||||
private static extern int ShowCursor(bool bShow);
|
||||
#endregion
|
||||
|
||||
// 获取 DPI 缩放因子
|
||||
#region 插件化动态设置页面核心逻辑
|
||||
private void LoadPluginSettingsPages()
|
||||
{
|
||||
try
|
||||
{
|
||||
// 扫描程序目录下Plugins文件夹中的插件dll
|
||||
var pluginCatalog = new DirectoryCatalog("./Plugins", "*.dll");
|
||||
var container = new CompositionContainer(pluginCatalog);
|
||||
container.ComposeParts(this);
|
||||
|
||||
// 将插件页面注册到页面映射字典
|
||||
foreach (var pluginPage in _pluginPages)
|
||||
{
|
||||
if (!_pageTypes.ContainsKey(pluginPage.PageTag))
|
||||
{
|
||||
_pageTypes.Add(pluginPage.PageTag, pluginPage.PageType);
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
// 插件加载失败不影响主程序运行,仅输出调试日志
|
||||
System.Diagnostics.Debug.WriteLine($"插件加载失败: {ex.Message}");
|
||||
}
|
||||
}
|
||||
|
||||
private void InitializeNavigationMenu()
|
||||
{
|
||||
// 自动将插件页面添加到导航菜单
|
||||
foreach (var pluginPage in _pluginPages)
|
||||
{
|
||||
var navItem = new NavigationViewItem
|
||||
{
|
||||
Tag = pluginPage.PageTag,
|
||||
Content = pluginPage.PageTitle,
|
||||
Icon = new FontIcon { Glyph = pluginPage.PageIconCode }
|
||||
};
|
||||
|
||||
if (pluginPage.IsFooterItem)
|
||||
{
|
||||
NavigationViewControl.FooterMenuItems.Add(navItem);
|
||||
}
|
||||
else
|
||||
{
|
||||
NavigationViewControl.MenuItems.Add(navItem);
|
||||
}
|
||||
}
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region 高DPI/多屏自适应窗口控制
|
||||
private void SetMaxSizeAndCenter()
|
||||
{
|
||||
if (!this.IsLoaded) return;
|
||||
|
||||
// 1. 获取窗口当前所在屏幕(而非固定主屏,彻底解决多屏问题)
|
||||
var windowHandle = new WindowInteropHelper(this).Handle;
|
||||
var currentScreen = Screen.FromHandle(windowHandle);
|
||||
var workingArea = currentScreen.WorkingArea;
|
||||
var screenBounds = currentScreen.Bounds;
|
||||
|
||||
// 2. 获取当前窗口的DPI缩放因子
|
||||
var source = PresentationSource.FromVisual(this);
|
||||
double dpiScaleX = 1.0;
|
||||
double dpiScaleY = 1.0;
|
||||
var source = System.Windows.PresentationSource.FromVisual(this);
|
||||
if (source != null)
|
||||
|
||||
if (source?.CompositionTarget != null)
|
||||
{
|
||||
dpiScaleX = source.CompositionTarget.TransformToDevice.M11;
|
||||
dpiScaleY = source.CompositionTarget.TransformToDevice.M22;
|
||||
}
|
||||
|
||||
// 先将物理像素转换为逻辑像素,再减去边距
|
||||
this.MaxWidth = (workingArea.Width / dpiScaleX) - 10;
|
||||
this.MaxHeight = (workingArea.Height / dpiScaleY) - 40;
|
||||
// 3. 物理像素 → WPF设备无关像素(DIP)转换
|
||||
double workAreaWidthDip = workingArea.Width / dpiScaleX;
|
||||
double workAreaHeightDip = workingArea.Height / dpiScaleY;
|
||||
double screenLeftDip = screenBounds.Left / dpiScaleX;
|
||||
double screenTopDip = screenBounds.Top / dpiScaleY;
|
||||
|
||||
// 确保窗口居中显示
|
||||
this.Left = (workingArea.Width / dpiScaleX - this.Width) / 2;
|
||||
this.Top = (workingArea.Height / dpiScaleY - this.Height) / 2;
|
||||
// 4. 设置窗口最大尺寸(保留你原有的边距)
|
||||
this.MaxWidth = workAreaWidthDip - 10;
|
||||
this.MaxHeight = workAreaHeightDip - 40;
|
||||
|
||||
// 5. 窗口在当前屏幕居中(解决副屏居中跑偏问题)
|
||||
this.Left = screenLeftDip + (workAreaWidthDip - this.ActualWidth) / 2;
|
||||
this.Top = screenTopDip + (workAreaHeightDip - this.ActualHeight) / 2;
|
||||
}
|
||||
|
||||
#region DPI/系统缩放变化监听
|
||||
private HwndSource _hwndSource;
|
||||
private void RegisterDpiChangedListener()
|
||||
{
|
||||
_hwndSource = PresentationSource.FromVisual(this) as HwndSource;
|
||||
_hwndSource?.AddHook(DpiChangedWndProc);
|
||||
}
|
||||
|
||||
private void UnregisterDpiChangedListener()
|
||||
{
|
||||
_hwndSource?.RemoveHook(DpiChangedWndProc);
|
||||
_hwndSource = null;
|
||||
}
|
||||
|
||||
private IntPtr DpiChangedWndProc(IntPtr hwnd, int msg, IntPtr wParam, IntPtr lParam, ref bool handled)
|
||||
{
|
||||
const int WM_DPICHANGED = 0x02E0;
|
||||
// 系统DPI/缩放变化时自动重新计算窗口参数
|
||||
if (msg == WM_DPICHANGED)
|
||||
{
|
||||
SetMaxSizeAndCenter();
|
||||
handled = true;
|
||||
}
|
||||
return IntPtr.Zero;
|
||||
}
|
||||
#endregion
|
||||
#endregion
|
||||
|
||||
#region 导航逻辑优化(含页面缓存)
|
||||
private void OnNavigationViewSelectionChanged(NavigationView sender, NavigationViewSelectionChangedEventArgs args)
|
||||
{
|
||||
// 处理自带的设置项导航
|
||||
if (args.IsSettingsSelected)
|
||||
{
|
||||
// 导航到设置页面
|
||||
NavigateToPage("Settings");
|
||||
NavigationViewControl.Header = "设置";
|
||||
return;
|
||||
}
|
||||
else if (args.SelectedItem is iNKORE.UI.WPF.Modern.Controls.NavigationViewItem item)
|
||||
|
||||
// 处理普通导航项
|
||||
if (args.SelectedItem is NavigationViewItem selectedItem)
|
||||
{
|
||||
// 检查是否有Tag,如果有则导航
|
||||
string tag = item.Tag as string;
|
||||
if (!string.IsNullOrEmpty(tag))
|
||||
string tag = selectedItem.Tag as string;
|
||||
if (!string.IsNullOrEmpty(tag) && _pageTypes.ContainsKey(tag))
|
||||
{
|
||||
// 检查当前页面是否已经是目标页面,避免重复导航
|
||||
// 避免重复导航到当前页面
|
||||
if (rootFrame.SourcePageType != _pageTypes[tag])
|
||||
{
|
||||
NavigateToPage(tag);
|
||||
}
|
||||
NavigationViewControl.Header = selectedItem.Content;
|
||||
}
|
||||
// 父级导航项(有子菜单)会自动展开,不需要额外处理
|
||||
}
|
||||
}
|
||||
|
||||
public void NavigateToPage(string pageTag)
|
||||
{
|
||||
if (_pageTypes.TryGetValue(pageTag, out Type pageType))
|
||||
{
|
||||
if (!_pageTypes.TryGetValue(pageTag, out Type pageType)) return;
|
||||
|
||||
try
|
||||
{
|
||||
// 使用Type参数导航,这样可以正确记录导航历史
|
||||
rootFrame.Navigate(pageType);
|
||||
// 更新标题
|
||||
if (NavigationViewControl.SelectedItem is iNKORE.UI.WPF.Modern.Controls.NavigationViewItem selectedItem)
|
||||
// 页面缓存:已创建的页面直接复用,保留状态,避免重复初始化
|
||||
if (!_pages.TryGetValue(pageTag, out var cachedPage))
|
||||
{
|
||||
NavigationViewControl.Header = selectedItem.Content;
|
||||
cachedPage = Activator.CreateInstance(pageType);
|
||||
_pages.Add(pageTag, cachedPage);
|
||||
}
|
||||
|
||||
// 导航到缓存页面
|
||||
rootFrame.Navigate(cachedPage.GetType(), cachedPage);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
iNKORE.UI.WPF.Modern.Controls.MessageBox.Show($"导航到页面时出错: {ex.Message}", "错误");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void OnControlsSearchBoxQuerySubmitted(AutoSuggestBox sender, AutoSuggestBoxQuerySubmittedEventArgs args)
|
||||
{
|
||||
string query = args.QueryText.ToLower();
|
||||
List<object> allItems = new List<object>();
|
||||
foreach (object item in NavigationViewControl.MenuItems) allItems.Add(item);
|
||||
foreach (object item in NavigationViewControl.FooterMenuItems) allItems.Add(item);
|
||||
|
||||
foreach (object item in allItems)
|
||||
{
|
||||
if (item is iNKORE.UI.WPF.Modern.Controls.NavigationViewItem navItem)
|
||||
{
|
||||
string content = navItem.Content?.ToString().ToLower();
|
||||
if (content != null && content.Contains(query))
|
||||
{
|
||||
NavigationViewControl.SelectedItem = navItem;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void OnControlsSearchBoxTextChanged(AutoSuggestBox sender, AutoSuggestBoxTextChangedEventArgs args)
|
||||
{
|
||||
if (args.Reason == AutoSuggestionBoxTextChangeReason.UserInput)
|
||||
{
|
||||
string query = sender.Text.ToLower();
|
||||
List<string> suggestions = new List<string>();
|
||||
|
||||
List<object> allItems = new List<object>();
|
||||
foreach (object item in NavigationViewControl.MenuItems) allItems.Add(item);
|
||||
foreach (object item in NavigationViewControl.FooterMenuItems) allItems.Add(item);
|
||||
|
||||
foreach (object item in allItems)
|
||||
{
|
||||
if (item is iNKORE.UI.WPF.Modern.Controls.NavigationViewItem navItem)
|
||||
{
|
||||
string content = navItem.Content?.ToString();
|
||||
if (content != null && content.ToLower().Contains(query))
|
||||
{
|
||||
suggestions.Add(content);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
sender.ItemsSource = suggestions;
|
||||
MessageBox.Show($"导航到页面时出错: {ex.Message}", "错误", MessageBoxButton.OK, MessageBoxImage.Error);
|
||||
}
|
||||
}
|
||||
|
||||
private void OnNavigationViewBackRequested(NavigationView sender, NavigationViewBackRequestedEventArgs args)
|
||||
{
|
||||
if (rootFrame.CanGoBack)
|
||||
{
|
||||
rootFrame.GoBack();
|
||||
}
|
||||
if (rootFrame.CanGoBack) rootFrame.GoBack();
|
||||
}
|
||||
|
||||
private void OnRootFrameNavigated(object sender, NavigationEventArgs e)
|
||||
{
|
||||
// 更新NavigationView的选中状态
|
||||
Type pageType = rootFrame.SourcePageType;
|
||||
foreach (KeyValuePair<string, Type> kvp in _pageTypes)
|
||||
// 导航后同步导航项选中状态
|
||||
Type currentPageType = rootFrame.SourcePageType;
|
||||
|
||||
// 处理设置项的选中状态
|
||||
if (currentPageType == typeof(SettingsPage))
|
||||
{
|
||||
if (kvp.Value == pageType)
|
||||
NavigationViewControl.SelectedItem = NavigationViewControl.SettingsItem;
|
||||
NavigationViewControl.Header = "设置";
|
||||
return;
|
||||
}
|
||||
|
||||
// 同步其他页面的选中状态
|
||||
foreach (var kvp in _pageTypes)
|
||||
{
|
||||
// 找到对应的NavigationViewItem
|
||||
NavigationViewItem item = FindNavigationViewItemByTag(kvp.Key);
|
||||
if (item != null && NavigationViewControl.SelectedItem != item)
|
||||
if (kvp.Value == currentPageType)
|
||||
{
|
||||
NavigationViewControl.SelectedItem = item;
|
||||
NavigationViewControl.Header = item.Content;
|
||||
var targetItem = FindNavigationViewItemByTag(kvp.Key);
|
||||
if (targetItem != null && NavigationViewControl.SelectedItem != targetItem)
|
||||
{
|
||||
NavigationViewControl.SelectedItem = targetItem;
|
||||
NavigationViewControl.Header = targetItem.Content;
|
||||
}
|
||||
break;
|
||||
}
|
||||
@@ -193,42 +315,103 @@ namespace Ink_Canvas.Windows.SettingsViews2
|
||||
|
||||
private NavigationViewItem FindNavigationViewItemByTag(string tag)
|
||||
{
|
||||
// 遍历所有主菜单项
|
||||
foreach (object item in NavigationViewControl.MenuItems)
|
||||
// 遍历主菜单
|
||||
foreach (var item in NavigationViewControl.MenuItems)
|
||||
{
|
||||
if (item is NavigationViewItem navItem)
|
||||
{
|
||||
if (navItem.Tag as string == tag)
|
||||
{
|
||||
return navItem;
|
||||
}
|
||||
// 检查子菜单项
|
||||
foreach (object child in navItem.MenuItems)
|
||||
|
||||
// 遍历子菜单,自动展开父项
|
||||
foreach (var childItem in navItem.MenuItems)
|
||||
{
|
||||
if (child is NavigationViewItem childNavItem)
|
||||
if (childItem is NavigationViewItem childNavItem && childNavItem.Tag as string == tag)
|
||||
{
|
||||
if (childNavItem.Tag as string == tag)
|
||||
{
|
||||
// 展开父项
|
||||
navItem.IsExpanded = true;
|
||||
return childNavItem;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
// 遍历页脚菜单项
|
||||
foreach (object item in NavigationViewControl.FooterMenuItems)
|
||||
|
||||
// 遍历底部菜单
|
||||
foreach (var item in NavigationViewControl.FooterMenuItems)
|
||||
{
|
||||
if (item is NavigationViewItem navItem)
|
||||
{
|
||||
if (navItem.Tag as string == tag)
|
||||
if (item is NavigationViewItem navItem && navItem.Tag as string == tag)
|
||||
{
|
||||
return navItem;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region 搜索框逻辑优化
|
||||
private void OnControlsSearchBoxQuerySubmitted(AutoSuggestBox sender, AutoSuggestBoxQuerySubmittedEventArgs args)
|
||||
{
|
||||
if (string.IsNullOrWhiteSpace(args.QueryText)) return;
|
||||
|
||||
string query = args.QueryText.Trim().ToLower();
|
||||
var allNavItems = GetAllNavigationItems();
|
||||
|
||||
var targetItem = allNavItems.FirstOrDefault(item =>
|
||||
item.Content?.ToString().ToLower().Contains(query) == true);
|
||||
|
||||
if (targetItem != null)
|
||||
{
|
||||
NavigationViewControl.SelectedItem = targetItem;
|
||||
}
|
||||
}
|
||||
|
||||
private void OnControlsSearchBoxTextChanged(AutoSuggestBox sender, AutoSuggestBoxTextChangedEventArgs args)
|
||||
{
|
||||
if (args.Reason != AutoSuggestionBoxTextChangeReason.UserInput) return;
|
||||
|
||||
string query = sender.Text.Trim().ToLower();
|
||||
var suggestions = new List<string>();
|
||||
|
||||
if (!string.IsNullOrEmpty(query))
|
||||
{
|
||||
var allNavItems = GetAllNavigationItems();
|
||||
suggestions = allNavItems
|
||||
.Where(item => item.Content?.ToString().ToLower().Contains(query) == true)
|
||||
.Select(item => item.Content.ToString())
|
||||
.ToList();
|
||||
}
|
||||
|
||||
sender.ItemsSource = suggestions;
|
||||
}
|
||||
|
||||
// 统一获取所有导航项(主菜单+子菜单+底部菜单+插件页面)
|
||||
private List<NavigationViewItem> GetAllNavigationItems()
|
||||
{
|
||||
var items = new List<NavigationViewItem>();
|
||||
|
||||
// 主菜单+子菜单
|
||||
foreach (var item in NavigationViewControl.MenuItems)
|
||||
{
|
||||
if (item is NavigationViewItem navItem)
|
||||
{
|
||||
items.Add(navItem);
|
||||
foreach (var child in navItem.MenuItems)
|
||||
{
|
||||
if (child is NavigationViewItem childNavItem)
|
||||
items.Add(childNavItem);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 底部菜单
|
||||
foreach (var item in NavigationViewControl.FooterMenuItems)
|
||||
{
|
||||
if (item is NavigationViewItem navItem)
|
||||
items.Add(navItem);
|
||||
}
|
||||
|
||||
return items;
|
||||
}
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user