在WPF中自定义控件(3) CustomControl (上)
来源:互联网 发布:java web高级编程豆瓣 编辑:程序博客网 时间:2024/06/11 04:40
在WPF中自定义控件(3) CustomControl (上)
周银辉
为快速地为你的应用定制一个零部件,你需要的是UserControl,这可以参考在WPF中自定义控件(2) UserControl, 为了让你打造的控件更标准化,更灵活以及更具有普遍意义,你需要用到的CustomControl,这正是本文要介绍的.
1,新建CustomControl
在选择控件基类后,第一件事情便是在你的项目中新建"CustomControl",我们会发现在项目中自动生成了一个*.CS(或*.VB或其他)文件以及/Themes/Generic.xaml(如果原来没有的话),他们分别是CustomControl的后台代码文件(Code Behind)与控件的默认主题文件,打开/Themes/Generic.xaml,你会发现其中自动生成了一个Style,这是你的控件的默认样式,正如WPF内置控件也有它的默认样式一样.这时,我们的工作就被分成了两个部分,一是在XXX.cs文件中编辑控件逻辑,而是在Generic.xaml中编写其UI.
2,Generic.xaml中的Style是如何与我们的控件联系在一起的
打开XXX.cs文件,你会发现静态构造方法中,VS自动地帮你覆盖了控件的DefaultStyleKey值:
static CustomControl1()
{
DefaultStyleKeyProperty.OverrideMetadata(typeof(CustomControl1), new FrameworkPropertyMetadata(typeof(CustomControl1)));
}我们知道DefaultStyleKeyProperty是FrameworkElement以及FrameworkContentElement类用来指示控件的默认样式键值的属性,该属性有一个很特别的地方就是我们不能够用继承的思想来思考它,比如说Button的默认样式键值是Style1,其子类MyButton的默认样式键值是Style2(或者没有指定默认样式),尽管MyButton可以向上转型成Button类,但我们并不希望其转型后的默认样式键值为Style1.所以WPF采用了在子类控件的静态构造方法中重写DefaultStyleKey元数据的方式来指定该子类控件的默认样式.上面代码中,我们将new FrameworkPropertyMetadata(typeof(CustomControl1))指定为其新的元数据值,这个值代表着,我们将在资源字典中查找一个键值为typeof(CustomControl1)的Style来做为控件的默认样式.而这个样式刚好被我们定义在了Generic.xaml中:
<Style TargetType="{x:Type local:CustomControl1}">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type local:CustomControl1}">
<Border Background="{TemplateBinding Background}"
BorderBrush="{TemplateBinding BorderBrush}"
BorderThickness="{TemplateBinding BorderThickness}">
</Border>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
这是大家可能有个疑问,上面XAML中的Style并没有指定Key值啊,而我们的控件要求的默认样式Key值为typeof(CustomControl1), 并且资源字典中的元素肯定是要有Key的? 这是Style的基本知识了,在WPF中,为Style指定Key时有两种方式:一是明确指定Key,而是在没有明确指定Key的情况下指定TargetType,WPF会自动地将其可Key设置为typeof(TargetType).如果你有在Blend中为控件打造Style的经验的话,你会注意到新建一个Style时,Blend会提供一个"Apply to ALL"选项,这也是为什么你打造的Style可以"Apply to all"的奥秘所在.
3, "Generic.xaml"这个名称并非偶然
通过上面的叙述,你可能会有冲动将Generic.xaml中的Style代码剪切出来,粘贴到任何一个我们的控件可以找到的地方,然后把Generic.xaml删掉或改成更优雅的名称,如果你运气好的话,这是可行的,因为控件会自下而上(Page,App,Theme)去查找其所需要的Style,但此时你已经犯了一个潜在的错误:你没有为控件提供默认的样式.这里的默认样式其实是说"在默认主题中或没有为该控件找到当前操作系统对应的主题时采用的的样式".这涉及到WPF中Theme的相关话题了,有兴趣可以参考msdn相关SDK.
4,打造你的控件逻辑
这是必然的,添加属性,添加事件,方法等等,这些你可以参考在WPF中自定义控件(2) UserControl ,这里就不重复叙述了.
5,打造控件UI
这里值得一提的是我非常佩服在VS的XAML海洋里"裸泳"的兄弟们,不过我更推荐使用Microsoft Expression Blend来完成这项艰巨的任务.另外,如果你发现WPF内置控件在Blend中很好用而我们自己打造的控件却不是这样,那么请注意了,你的控件逻辑可能设计得不规范.
6,控件UI部分与逻辑部分的耦合度.
这是一个容易被忽略但却非常重要的问题, 我们之所以使用CustomControl而不是UserControl,是因为我们希望自己的控件能向WPF内置控件一样,其UI能轻易地被其他用户定制或我们将来所改变.也就是说其视觉树不能与后台逻辑纠缠在一起,因为其视觉树中的元素完全可能被你的控件用户改变.比如,如果你的控件的视觉树中有一个Button,而你在该Button的Click事件中做了一些控件的逻辑处理,那么很可能你的控件打造失败了,因为该Button可能会在用户重新定义控件Template时被删除.
关于如何将这种耦合降到最低,敬请关注"在WPF中自定义控件(3) CustomControl (下)"
周银辉
为快速地为你的应用定制一个零部件,你需要的是UserControl,这可以参考在WPF中自定义控件(2) UserControl, 为了让你打造的控件更标准化,更灵活以及更具有普遍意义,你需要用到的CustomControl,这正是本文要介绍的.
1,新建CustomControl
在选择控件基类后,第一件事情便是在你的项目中新建"CustomControl",我们会发现在项目中自动生成了一个*.CS(或*.VB或其他)文件以及/Themes/Generic.xaml(如果原来没有的话),他们分别是CustomControl的后台代码文件(Code Behind)与控件的默认主题文件,打开/Themes/Generic.xaml,你会发现其中自动生成了一个Style,这是你的控件的默认样式,正如WPF内置控件也有它的默认样式一样.这时,我们的工作就被分成了两个部分,一是在XXX.cs文件中编辑控件逻辑,而是在Generic.xaml中编写其UI.
2,Generic.xaml中的Style是如何与我们的控件联系在一起的
打开XXX.cs文件,你会发现静态构造方法中,VS自动地帮你覆盖了控件的DefaultStyleKey值:
![](/Images/OutliningIndicators/None.gif)
![](/Images/OutliningIndicators/ExpandedBlockStart.gif)
![](/Images/OutliningIndicators/InBlock.gif)
![](/Images/OutliningIndicators/ExpandedBlockEnd.gif)
![](/Images/OutliningIndicators/None.gif)
![](/Images/OutliningIndicators/None.gif)
![](/Images/OutliningIndicators/None.gif)
![](/Images/OutliningIndicators/None.gif)
![](/Images/OutliningIndicators/None.gif)
![](/Images/OutliningIndicators/None.gif)
![](/Images/OutliningIndicators/None.gif)
![](/Images/OutliningIndicators/None.gif)
![](/Images/OutliningIndicators/None.gif)
![](/Images/OutliningIndicators/None.gif)
![](/Images/OutliningIndicators/None.gif)
![](/Images/OutliningIndicators/None.gif)
![](/Images/OutliningIndicators/None.gif)
![](/Images/OutliningIndicators/None.gif)
3, "Generic.xaml"这个名称并非偶然
通过上面的叙述,你可能会有冲动将Generic.xaml中的Style代码剪切出来,粘贴到任何一个我们的控件可以找到的地方,然后把Generic.xaml删掉或改成更优雅的名称,如果你运气好的话,这是可行的,因为控件会自下而上(Page,App,Theme)去查找其所需要的Style,但此时你已经犯了一个潜在的错误:你没有为控件提供默认的样式.这里的默认样式其实是说"在默认主题中或没有为该控件找到当前操作系统对应的主题时采用的的样式".这涉及到WPF中Theme的相关话题了,有兴趣可以参考msdn相关SDK.
4,打造你的控件逻辑
这是必然的,添加属性,添加事件,方法等等,这些你可以参考在WPF中自定义控件(2) UserControl ,这里就不重复叙述了.
5,打造控件UI
这里值得一提的是我非常佩服在VS的XAML海洋里"裸泳"的兄弟们,不过我更推荐使用Microsoft Expression Blend来完成这项艰巨的任务.另外,如果你发现WPF内置控件在Blend中很好用而我们自己打造的控件却不是这样,那么请注意了,你的控件逻辑可能设计得不规范.
6,控件UI部分与逻辑部分的耦合度.
这是一个容易被忽略但却非常重要的问题, 我们之所以使用CustomControl而不是UserControl,是因为我们希望自己的控件能向WPF内置控件一样,其UI能轻易地被其他用户定制或我们将来所改变.也就是说其视觉树不能与后台逻辑纠缠在一起,因为其视觉树中的元素完全可能被你的控件用户改变.比如,如果你的控件的视觉树中有一个Button,而你在该Button的Click事件中做了一些控件的逻辑处理,那么很可能你的控件打造失败了,因为该Button可能会在用户重新定义控件Template时被删除.
关于如何将这种耦合降到最低,敬请关注"在WPF中自定义控件(3) CustomControl (下)"
- 在WPF中自定义控件(3) CustomControl (上)
- 在WPF中自定义控件(3) CustomControl (上)
- 在WPF中自定义控件(3) CustomControl (上)
- 在WPF中自定义控件(3) CustomControl (上)
- 在WPF中自定义控件 CustomControl
- 在WPF中自定义控件 CustomControl
- 在WPF中自定义控件 CustomControl
- 在WPF中自定义控件(3) CustomControl (下)
- 在WPF中自定义控件(3) CustomControl (下)
- 在WPF中自定义控件(3) CustomControl (下)
- 在WPF中自定义控件
- 在WPF中自定义控件
- WPF之路——用户控件对比自定义控件(UserControl VS CustomControl)
- WPF CustomControl
- 在WPF中自定义控件(2) UserControl
- 在WPF中自定义控件(1)
- 在WPF中自定义控件(2) UserControl
- 在WPF中自定义控件(1)
- 谈谈WPF中的CollectionView与CollectionViewSource (1)
- 在WPF中自定义控件(3) CustomControl (下)
- Got my offer from GE
- XPath语法备忘
- WPF Can Do
- 在WPF中自定义控件(3) CustomControl (上)
- DEV—WOW 大赛信息
- 关于让WPF软件界面支持全球化和本地化
- Expression Blend 2 September Preview 发布
- 在WPF中自定义控件(2) UserControl
- [WPF实践之路] 目录导航
- 自定义WPF面板
- 在WPF中自定义控件(1)
- 为WPF项目创建单元测试
原创粉丝点击
热门IT博客
热门问题
老师的惩罚
人脸识别
我在镇武司摸鱼那些年
重生之率土为王
我在大康的咸鱼生活
盘龙之生命进化
天生仙种
凡人之先天五行
春回大明朝
姑娘不必设防,我是瞎子
黄金现货价格
长江现货铜价
黄金现货即时价格
长江现货价今日价格
现货黄金走势
现货黄金行情
今日现货黄金价格走势图
今日现货黄金价格
今日现货黄金价格走势
白银现货价格走势图
今日黄金现货价格走势图
聊城市钢管现货网
长江现货金属网
聊城钢管现货网网
今日现货黄金走势与分析
聊城钢管现货钢管网
现货白银走势图
今日长江现货铜价格表
中国钢铁现货网
今日现货黄金
长江现货铜价今日铜价
现货白银价格
今日长江现货铜价
不锈钢现货超市
pta现货价格走势图
聊城现货钢管网
现货黄金走势图
现货白银走势
国际现货黄金价格走势图
今日黄金现货走势图
今天现货黄金价格走势图
黄金现货交易时间
长江现货铝锭
菜粕现货价格
甲醇现货价格
金银现货交易
现货跟期货的区别
钢之家现货报价
长江铝锭现货价格
长江现货铝价
长江现货铝锭价格