ARTICLE DETAIL

资讯详情

深耕网站建设、视觉设计与SEO优化的一线实战洞察。

UWP 标题栏定制实战:基于 Windows-universal-samples TitleBar 示例的四种自定义方案

UWP 标题栏定制实战:基于 Windows-universal-samples TitleBar 示例的四种自定义方案 示例工程【免费下载链接】Windows-universal-samplesAPI samples for the Universal Windows Platform.项目地址https://gitcode.com/gh_mirrors/wi/Windows-universal-samples点击查看免费下载本指南以 Windows-universal-samples 仓库中的 TitleBar 示例Samples/TitleBar/README.md为骨架完整讲解 UWP 应用中标题栏自定义的四种核心技术定制系统标题栏颜色、将视图扩展到标题栏区域绘制自定义标题栏、响应标题栏状态变化以及在标题栏中绘制控件。读完本文你将掌握ApplicationViewTitleBar与CoreApplicationViewTitleBar两套 API 的完整用法并能直接照搬示例代码到自己的 UWP 项目中。示例概览一个示例四种标题栏定制技巧TitleBar 示例是一个典型的 UWP 功能演示sample属于ControlsLayoutAndText类别其 frontmatter 声明了它支持 C#、C/CX 与 C/WinRT 三种语言版本仓库中对应cs/、cpp/、cppwinrt/三个子目录。示例演示了以下四种标题栏定制技术定制标准系统标题栏中的颜色不改变标题栏布局只通过 API 修改标题栏背景、前景以及最小化/最大化/关闭按钮的配色。将视图扩展到标题栏区域开启ExtendViewIntoTitleBar后应用可以渲染到原本由系统标题栏占据的空间从而绘制完全自定义的标题栏。响应标题栏状态变化订阅LayoutMetricsChanged、IsVisibleChanged等事件在标题栏尺寸、可见性、全屏模式变化时动态调整应用 UI。在标题栏中绘制控件仅 XAML 可用通过Window.SetTitleBar把自定义元素指定为标题栏的可拖动区域并在其中放置 CheckBox 等交互控件。需要注意的是并非所有标题栏功能在所有 Windows 10 构建版本中都可用功能会随新版本逐步发布示例运行环境要求为 Windows 10并使用 Visual Studio 构建。从源码结构看示例由两个可切换的场景页组成注册于 SampleConfiguration.csListScenario scenarios new ListScenario { new Scenario() { TitleCustom colors, ClassTypetypeof(Scenario1_Colors)}, new Scenario() { TitleCustom drawing, ClassTypetypeof(Scenario2_Extend)}, };Scenario1Custom colors演示标题栏及按钮颜色定制Scenario2Custom drawing演示视图扩展进标题栏、全屏模式切换与自定义标题栏的挂载/移除。系统要求按示例 README 的说明运行本示例需要Windows 10操作系统Microsoft Visual Studio用于构建与部署 UWP 应用。标题栏相关 API 属于Windows.UI.ViewManagement与Windows.ApplicationModel.Core命名空间仅在 UWP 应用模型中可用。构建示例示例 README 给出了标准的构建流程按以下步骤操作即可若下载的是 samples ZIP 压缩包务必解压整个压缩包而不仅是包含目标示例的单个文件夹——仓库中的示例共享SharedContent依赖只解压局部会导致构建失败压缩包结构同时包含SharedContent与LICENSE见 README frontmatter 的extendedZipContent声明。启动 Visual Studio选择FileOpenProject/Solution。在解压目录下依次进入 Samples 子文件夹 → 本示例文件夹TitleBar→ 选择语言子目录C# 对应cs/、C/CX 对应cpp/、C/WinRT 对应cppwinrt/双击其中的解决方案文件.sln。按CtrlShiftB或选择BuildBuild Solution完成构建。运行示例构建成功后部署与运行方式取决于你的需求仅部署选择BuildDeploy Solution。部署并调试运行按F5或选择DebugStart Debugging。部署但不调试运行按CtrlF5或选择DebugStart Without Debugging。场景一自定义标题栏颜色ApplicationViewTitleBar示例的第一种定制方式是不改布局、只改配色。核心对象是ApplicationView.GetForCurrentView().TitleBar类型为ApplicationViewTitleBar。场景页在构造函数中获取该对象并依据当前颜色状态反推单选按钮见 Scenario1_Colors.xaml.cstitleBar ApplicationView.GetForCurrentView().TitleBar; // Infer the radio button selection from the title bar colors. if (titleBar.ButtonBackgroundColor null) { UseStandardColors.IsChecked true; } else if (titleBar.ButtonBackgroundColor.Value.A 0) { UseCustomColors.IsChecked true; } else { TransparentWhenExtended.IsChecked true; }可定制的 12 个颜色属性ApplicationViewTitleBar共暴露 12 个可写颜色属性覆盖标题栏主体与按钮两套状态活动/非活动、默认/悬停/按下。示例 UIScenario1_Colors.xaml通过数据绑定实时展示这些属性完整清单如下类别属性说明标题栏背景BackgroundColor窗口活动时的标题栏背景色标题栏前景ForegroundColor窗口活动时的标题栏文字/图标前景色标题栏背景非活动InactiveBackgroundColor窗口非活动时的背景色标题栏前景非活动InactiveForegroundColor窗口非活动时的前景色按钮背景ButtonBackgroundColor最小化/最大化/关闭按钮默认背景色按钮悬停背景ButtonHoverBackgroundColor按钮悬停时的背景色按钮按下背景ButtonPressedBackgroundColor按钮按下时的背景色按钮非活动背景ButtonInactiveBackgroundColor窗口非活动时按钮的背景色按钮前景ButtonForegroundColor按钮默认前景色按钮悬停前景ButtonHoverForegroundColor按钮悬停时的前景色按钮按下前景ButtonPressedForegroundColor按钮按下时的前景色按钮非活动前景ButtonInactiveForegroundColor窗口非活动时按钮的前景色恢复系统默认颜色赋值为 null示例中Use standard colors单选按钮的处理逻辑展示了恢复默认的正确做法——将所有 12 个属性显式置为null见 Scenario1_Colors.xaml.cs// Setting colors to null returns them to system defaults. titleBar.BackgroundColor null; titleBar.ForegroundColor null; titleBar.InactiveBackgroundColor null; titleBar.InactiveForegroundColor null; titleBar.ButtonBackgroundColor null; titleBar.ButtonHoverBackgroundColor null; titleBar.ButtonPressedBackgroundColor null; titleBar.ButtonInactiveBackgroundColor null; titleBar.ButtonForegroundColor null; titleBar.ButtonHoverForegroundColor null; titleBar.ButtonPressedForegroundColor null; titleBar.ButtonInactiveForegroundColor null;因此判断某颜色是否被自定义时应检查对应属性是否为null这也是示例代码反推单选按钮状态的依据。Alpha 通道的语义关键细节示例源码中注释与取值逻辑给出了一个容易踩坑的规则Scenario1_Colors.xaml.cs// Title bar colors. Alpha must be 255. titleBar.BackgroundColor new Color() { A 255, R 54, G 60, B 116 }; titleBar.ForegroundColor new Color() { A 255, R 232, G 211, B 162 }; titleBar.InactiveBackgroundColor new Color() { A 255, R 135, G 141, B 199 }; titleBar.InactiveForegroundColor new Color() { A 255, R 232, G 211, B 162 }; // Title bar button background colors. Alpha is respected when the view is extended // into the title bar (see scenario 2). Otherwise, Alpha is ignored and treated as if it were 255. byte buttonAlpha (byte)(TransparentWhenExtended.IsChecked.Value ? 0 : 255); titleBar.ButtonBackgroundColor new Color() { A buttonAlpha, R 54, G 60, B 116 }; titleBar.ButtonHoverBackgroundColor new Color() { A buttonAlpha, R 19, G 21, B 40 }; titleBar.ButtonPressedBackgroundColor new Color() { A buttonAlpha, R 232, G 211, B 162 }; titleBar.ButtonInactiveBackgroundColor new Color() { A buttonAlpha, R 135, G 141, B 199 }; // Title bar button foreground colors. Alpha must be 255. titleBar.ButtonForegroundColor new Color() { A 255, R 232, G 211, B 162 }; titleBar.ButtonHoverForegroundColor new Color() { A 255, R 255, G 255, B 255 }; titleBar.ButtonPressedForegroundColor new Color() { A 255, R 54, G 60, B 116 }; titleBar.ButtonInactiveForegroundColor new Color() { A 255, R 232, G 211, B 162 };归纳为三条规则标题栏本体颜色背景/前景含活动与非活动的 Alpha 必须为 255即不支持半透明标题栏。按钮背景色的 Alpha 仅在视图扩展进标题栏时被尊重未扩展时 Alpha 被忽略、按 255 处理。示例中的Transparent when extended模式即利用这一点将按钮背景 Alpha 设为 0使按钮在自定义标题栏背景下隐形仅在扩展模式下生效。按钮前景色的 Alpha 必须为 255。场景二将视图扩展到标题栏CoreApplicationViewTitleBar第二种定制方式彻底接管标题栏外观。其核心开关是CoreApplication.GetCurrentView().TitleBar.ExtendViewIntoTitleBar。场景页的 CheckBox 与它双向同步见 Scenario2_Extend.xaml.csprivate void ExtendView_Click(object sender, RoutedEventArgs e) { bool extend ExtendView.IsChecked.Value; CoreApplication.GetCurrentView().TitleBar.ExtendViewIntoTitleBar extend; EnableControls.Visibility extend ? Visibility.Visible : Visibility.Collapsed; if (extend) { rootPage.AddCustomTitleBar(); } else { rootPage.RemoveCustomTitleBar(); } }开启后应用即可在原本被系统标题栏占据的空间中自由绘制同时标题栏按钮背景的 Alpha 通道开始生效对应场景一中的规则 2。此时必须借助CoreApplicationViewTitleBar的布局属性让自定义标题栏与系统标题栏在尺寸和位置上精确对齐。布局指标Height 与 SystemOverlay 内边距CoreApplicationViewTitleBar提供三个关键布局来源示例通过INotifyPropertyChanged数据绑定把它们喂给 XAML见 CustomTitleBar.xaml.cspublic Thickness CoreTitleBarPadding { get { // The SystemOverlayLeftInset and SystemOverlayRightInset values are // in terms of physical left and right. Therefore, we need to flip // then when our flow direction is RTL. if (FlowDirection FlowDirection.LeftToRight) { return new Thickness() { Left coreTitleBar.SystemOverlayLeftInset, Right coreTitleBar.SystemOverlayRightInset }; } else { return new Thickness() { Left coreTitleBar.SystemOverlayRightInset, Right coreTitleBar.SystemOverlayLeftInset }; } } } public double CoreTitleBarHeight { get { return coreTitleBar.Height; } }属性用途Height系统标题栏的高度用于给自定义标题栏 Grid 定高SystemOverlayLeftInset左侧系统 UI 区域宽度含窗口按钮等系统叠加元素用于给自定义标题栏内容留出左侧安全边距SystemOverlayRightInset右侧系统 UI 区域宽度如最小化/最大化/关闭按钮占位用于留出右侧安全边距IsVisible标题栏当前是否可见全屏模式下可能隐藏示例 XAMLCustomTitleBar.xaml将二者直接绑定到布局Grid x:NameTitleBar VerticalAlignmentTop Height{x:Bind CoreTitleBarHeight, ModeOneWay} Canvas.ZIndex3 Rectangle x:NameBackgroundElement FillDarkGreen / Grid Padding{x:Bind CoreTitleBarPadding, ModeOneWay} Grid.ColumnDefinitions ColumnDefinition Width*/ ColumnDefinition WidthAuto/ /Grid.ColumnDefinitions TextBlock Grid.Column0 TextCustom Title Bar FontStyleItalic/ CheckBox Grid.Column1 x:NameTitleBarControl VisibilityCollapsedCheckbox in title bar/CheckBox /Grid /GridC/WinRT 版本的实现在 CustomTitleBar.cpp 中逻辑一致并通过ThicknessHelper::FromLengths构造内边距同样处理了 RTL 翻转。响应状态变化三个关键事件要让自定义标题栏始终与系统状态同步必须订阅以下事件见 CustomTitleBar.xaml.csvoid CustomTitleBar_Loaded(object sender, RoutedEventArgs e) { coreTitleBar.LayoutMetricsChanged OnLayoutMetricsChanged; coreTitleBar.IsVisibleChanged OnIsVisibleChanged; // The SizeChanged event is raised when the view enters or exits full screen mode. Window.Current.SizeChanged OnWindowSizeChanged; UpdateLayoutMetrics(); UpdatePositionAndVisibility(); }事件触发时机示例中的处理CoreApplicationViewTitleBar.LayoutMetricsChanged标题栏布局指标变化如高度、inset 变化重新通知CoreTitleBarHeight/CoreTitleBarPadding绑定CoreApplicationViewTitleBar.IsVisibleChanged标题栏可见性变化全屏模式重新计算标题栏的 Visibility 与所在行Window.Current.SizeChanged窗口尺寸变化进出全屏时触发同上重新定位标题栏与之对应的CustomTitleBar_Unloaded中必须逐一注销事件-避免悬挂引用导致泄漏。C/WinRT 版本在 CustomTitleBar.cpp 中用revoker令牌token完成订阅与退订。全屏模式下的布局策略示例用两层 Grid 实现普通模式标题栏占一行、全屏模式标题栏浮于内容之上的效果。其注释给出了清晰的布局示意CustomTitleBar.xaml.cs// When not in full screen mode, the grid looks like this: // Row 0: Custom-rendered title bar // Row 1: Rest of content // // In full screen mode, the the grid looks like this: // Row 0: (empty) // Row 1: Custom-rendered title bar // Row 1: Rest of contentvoid UpdatePositionAndVisibility() { if (ApplicationView.GetForCurrentView().IsFullScreenMode) { // In full screen mode, the title bar overlays the content. TitleBar.Visibility coreTitleBar.IsVisible ? Visibility.Visible : Visibility.Collapsed; Grid.SetRow(TitleBar, 1); } else { // When not in full screen mode, the title bar is visible and does not overlay content. TitleBar.Visibility Visibility.Visible; Grid.SetRow(TitleBar, 0); } }场景二页面还提供全屏模式切换演示Scenario2_Extend.xaml.cs通过ApplicationView.GetForCurrentView().TryEnterFullScreenMode()进入全屏、ExitFullScreenMode()退出并监听Window.Current.SizeChanged更新按钮图标与状态文本。自定义标题栏的挂载包装页面内容MainPage.AddCustomTitleBar()SampleConfiguration.cs展示了正确的挂载方式把页面原有内容摘出来塞进自定义标题栏控件的第二行再把自定义标题栏整体设为窗口内容public void AddCustomTitleBar() { if (customTitleBar null) { customTitleBar new CustomTitleBar(); customTitleBar.EnableControlsInTitleBar(areControlsInTitleBar); UIElement mainContent this.Content; this.Content null; customTitleBar.SetPageContent(mainContent); this.Content customTitleBar; } } public void RemoveCustomTitleBar() { if (customTitleBar ! null) { this.Content customTitleBar.SetPageContent(null); customTitleBar null; } }SetPageContent在RootGrid中维护内容元素并固定放置到第 1 行C/WinRT 对应实现见 CustomTitleBar.cpp。另外C# 版本通过 Themes/Generic.xaml 为CustomTitleBar提供了默认控件模板模板内仅是一个绑定背景/边框属性的 Border。在标题栏中绘制控件Window.SetTitleBar仅 XAML标题栏区域默认会将所有鼠标点击视为拖动窗口操作若要在其中放置 CheckBox 等交互控件必须显式声明可拖动区域。示例通过Window.Current.SetTitleBar实现CustomTitleBar.xaml.cspublic void EnableControlsInTitleBar(bool enable) { if (enable) { TitleBarControl.Visibility Visibility.Visible; // Clicks on the BackgroundElement will be treated as clicks on the title bar. Window.Current.SetTitleBar(BackgroundElement); } else { TitleBarControl.Visibility Visibility.Collapsed; Window.Current.SetTitleBar(null); } }要点SetTitleBar(BackgroundElement)把标题栏中的矩形背景指定为可拖动区域同时该区域之外的标题栏元素如 CheckBox就可以正常接收点击。传入null则取消自定义拖动区域恢复系统行为。该 API仅 XAML 应用可用README 明确标注 Drawing controls in the title bar (XAML only)C/WinRT 版本的等价调用见 CustomTitleBar.cpp。相关主题与延伸阅读标题栏定制主要围绕以下两个 API 家族展开Windows.UI.ViewManagement.ApplicationView/ApplicationViewTitleBar负责颜色定制与全屏模式管理IsFullScreenMode、TryEnterFullScreenMode、ExitFullScreenMode。Windows.ApplicationModel.Core.CoreApplicationViewTitleBar负责视图扩展、布局指标与状态事件ExtendViewIntoTitleBar、Height、SystemOverlayLeftInset/RightInset、IsVisible、LayoutMetricsChanged、IsVisibleChanged。仓库中与本示例直接相关的资源FullScreenMode 示例本示例 README 的 Related samples 中明确关联的姊妹示例专门演示全屏模式 API与场景二的全屏切换逻辑互相印证。原 README 还提及一个 JavaScriptWinJS版本的 TitleBar 示例该版本已归档现仓库仅维护 C#、C/CX 与 C/WinRT 版本分别位于 cs、cpp、cppwinrt 子目录。小结TitleBar 示例完整覆盖了 UWP 标题栏定制的四种典型手法从最简单的 12 个颜色属性配置到视图扩展、状态事件响应再到 XAML 专属的标题栏控件嵌入是一个可以直接照搬的最小可用实现。实际项目中可按需组合仅在品牌色要求下修改ApplicationViewTitleBar颜色需要沉浸式界面时开启ExtendViewIntoTitleBar并配合CoreApplicationViewTitleBar的布局指标绘制自定义标题栏同时务必留意 Alpha 通道规则与功能随 Windows 10 版本逐步开放的限制。赞分享示例工程【免费下载链接】Windows-universal-samplesAPI samples for the Universal Windows Platform.项目地址https://gitcode.com/gh_mirrors/wi/Windows-universal-samples点击查看免费下载相关推荐UWP 焦点可视化Focus Visuals实战系统绘制与自定义焦点边框 —— 基于 Windows-universal-samples 的 XamlFocusVisuals 示例解析UWP 焦点可视化Focus Visuals实战系统绘制与自定义焦点边框 —— 基于 Windows universal samples 的 XamlFo示例工程Windows-universal-samples用 ActivitySensor 实现 UWP 活动检测的四种场景实战JavaScript 存档示例Windows universal samples用 ActivitySensor 实现 UWP 活动检测的四种场景实战JavaScript 存档示例 本示例工程SleeperXmacOS系统级电源管理框架的技术实现与应用SleeperXmacOS系统级电源管理框架的技术实现与应用 在macOS生态系统中电源管理一直是一个复杂而关键的技术领域。对于需要在特定场景下保持系统活跃示例工程上一篇Rustix终极指南如何用安全系统调用封装库提升开发效率下一篇Git常用命令速查Front-end-articles版本控制最佳实践创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表