WPF --- 如何重写WPF原生控件样式

引言

上一篇中 WPF --- 重写DataGrid样式,因新产品UI需要,重写了一下微软 WPF 原生的 DataGrid 的样式,包含如下内容:

  • 基础设置,一些基本背景色,字体颜色等。
  • 滚动条样式。
  • 实现圆角表格,重写表格的一些基础样式,例如 CellStyleRowStyle,RowHeaderStyle, ColumnHeaderStyle等。

重写过程中,遇到了两个问题:

  1. 如何获取 WPF 原生的 DataGrid 的样式?
  2. 滚动条样式中,如何固定滚动条长度?

本篇文章分享一下这两个问题的解决办法。

解决方法

我来分别分享一下我遇到的这两个问题。

问题1

第一个,如何获取 WPF 原生的 DataGrid 的样式?

这个问题不限于原生的 DataGrid 的样式,其他的一些样式比如 checkBox,RadioButton, ComboBox

这些控件对于一些初学者来说,很难理解他是怎么实现的。

比如 ComboBox 控件,我刚开始学习WPF时的时候,我就不理解这个是怎么实现的,我后来还是通过查询微软官方文档 [1]ComboBox Styles and Templates ,文档里给出了 ComboBox StylesComboBox Templates ,看完设计代码之后才明白原生的ComBox控件是怎么实现的。

那么用翻阅官方文档的方式效率太低了,所以我这回找了一个效率很高的方法吗,就是是通过 Blend(全称:Microsoft Blend for Visual Studio) ,这个是跟随 Visual Studio 一起安装的,平常我也使用 Blend ,做一些自定义控件和动画效果等,十分好用。接下来演示一下如何获取 ComboBox 的原生样式。

第一步:

使用 Blend 创建一个 WPF 项目,再窗体中添加一个 ComboBox

第二步:

选中 ComboBox ,在设计视图左上角点击 ComboBox 下拉框,再点击"编辑模板",再点击"编辑副本"。

这时会弹出创建资源的窗体,可以选择你创建样式的形式是什么。

  • 关键字选项:可以选择你创建的样式是否带 Key,若不带 Key 则默认应用在所有该类型控件上。
  • 定义位置选项:"应用程序"选项会将该样式创建到 App.xaml 文件中。"此文档"选项会将该样式创建到当前窗体的 Window.Resources 中,最后一个"资源字典"选项,则会创建一个新的资源字典文件或者添加到已有资源字典文件。

第三步:

我这里选择,生成到当前文件 Window.Resources 中且带 Key 的样式,然后他就会生成原生的样式代码。如下所示,这里代码太多,折叠展示。

第四步:

可以看到它生成了一堆的资源,这时候我们只需要找我们想要的那一部分,比如 ComboBoxTemplate ,从代码中就可以看出,ComboBox 主要有三部分组成

  • Popup:它的作用就是当 ToggleButtonIsChecked 为true时,展开其内容,它的内容就是 ScrollViewer,就是我们看到的下拉弹出的内容了。
  • ToggleButton: 这个就是右侧那个上下尖括号符号按钮,用于打开或关闭 Popup 内容。
  • ContentPresenter:内容容器,可以自定义任何控件模板、数据模板或样式在其中展示。

所以,到此为止,我们就明白了原生的 ComboBox 是怎么实现的了,而且有了这个原生样式,就可以在此基础之上进行修改,美化,从而演变成我们想要的样子。

问题2

第二个问题, 滚动条样式中,如何固定滚动条长度?

在原生的滚动条样式中,纵方向上的滚动条的高度是跟随你窗口的大小和内容的多少而改变的,窗口大内容少,滚动条的高度就越大,反之亦然。

我调试了很久,包括重写 Thumb 的样式,修改 Thumb 的高度,都一直不生效,最后在官方文档 [2]How to: Customize the Thumb Size on a ScrollBar 中找到了解决方案,就是通过设置HorizontalScrollBarButtonWidthKey 来固定滚动条长度。文中将其

小结

Blend 本身就是一个专业级的界面设计工具,可以大大提高我们创建丰富、交互式的用户界面(UI)和用户体验(UX)设计的效率。

而通过 Blend 获取原生样式,阅读原生样式,非常有利于理解控件设计的,在此基础上进行修改,美化也是能够事半功倍的,强烈建议大家学会。

参考

1\] [https://learn.microsoft.com/en-us/dotnet/desktop/wpf/controls/combobox-styles-and-templates?view=netframeworkdesktop-4.8\&viewFallbackFrom=netdesktop-6.0](https://learn.microsoft.com/en-us/dotnet/desktop/wpf/controls/combobox-styles-and-templates?view=netframeworkdesktop-4.8&viewFallbackFrom=netdesktop-6.0) \[2\] [https://learn.microsoft.com/en-us/dotnet/desktop/wpf/controls/how-to-customize-the-thumb-size-on-a-scrollbar?view=netframeworkdesktop-4.8\&viewFallbackFrom=netdesktop-6.0](https://learn.microsoft.com/en-us/dotnet/desktop/wpf/controls/how-to-customize-the-thumb-size-on-a-scrollbar?view=netframeworkdesktop-4.8&viewFallbackFrom=netdesktop-6.0)

相关推荐
我好喜欢你~15 小时前
WPF---数据模版
wpf
hqwest2 天前
C#WPF实战出真汁07--【系统设置】--菜品类型设置
开发语言·c#·wpf·grid设计·stackpanel布局
hqwest2 天前
C#WPF实战出真汁08--【消费开单】--餐桌面板展示
c#·wpf·ui设计·wpf界面设计
orangapple2 天前
WPF 打印报告图片大小的自适应(含完整示例与详解)
c#·wpf
三千道应用题3 天前
WPF&C#超市管理系统(6)订单详情、顾客注册、商品销售排行查询和库存提示、LiveChat报表
开发语言·c#·wpf
✎ ﹏梦醒͜ღ҉繁华落℘4 天前
开发WPF项目时遇到的问题总结
wpf
hqwest4 天前
C#WPF实战出真汁06--【系统设置】--餐桌类型设置
c#·.net·wpf·布局·分页·命令·viewmodel
Vae_Mars5 天前
WPF中使用InputBindings进行快捷键绑定
wpf
hqwest5 天前
C#WPF实战出真汁05--左侧导航
开发语言·c#·wpf·主界面·窗体设计·视图viewmodel
hqwest5 天前
C#WPF实战出真汁01--项目介绍
开发语言·c#·wpf