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

引言

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

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

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

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

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

解决方法

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

问题1

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

这个问题不限于原生的 DataGrid 的样式,其他的一些样式比如 checkBox,RadioButtonComboBox等。这些控件对于一些初学者来说,很难理解他是怎么实现的。

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

那么用翻阅官方文档的方式效率太低了,所以我这回发现了一个效率很高的方法,就是是使用 「Blend(全称:Microsoft Blend for Visual Studio)」,Blend是跟随 Visual Studio 一起安装的,平常我也使用 Blend ,做一些自定义控件和动画效果等,是一个非常专业的工具。

接下来演示一下如何使用Blend获取 ComboBox 的原生样式。

「第一步:」

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

「第二步:」

选中 ComboBox ,在设计视图左上角点击 ComboBox 下拉框,再点击“编辑模板”,再点击“编辑副本”。WPF --- 如何重写WPF原生控件样式?

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

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

「第三步:」

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

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

「第四步:」

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

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

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

问题2

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

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

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

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

小结

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

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