原文:wpf控件设计时支持(2)

这篇介绍在wpf设计时集合项属性添加项的定义和自定义控件右键菜单的方法

集合项属性设计时支持

1.为集合属性设计器识别具体项类型

wpf设计器允许定义集合项的类型,如新发布的WPF的DataGrid控件,其中的Columns包括一下几种类型,Columns集合属性是以下几个类型的抽象类集合.要在设计器识别以下类型,就必须用到wpf设计时的扩展功能

实现这个功能很简单,只需要给该集合属性附上NewItemTypesAttribute元数据就好了.如下代码

NewItemTypesAttribute attr = new NewItemTypesAttribute(typeof(DataGridTextColumn),typeof(DataGridCheckBoxColumn),typeof(DataGridHyperlinkColumn),typeof(DataGridComboBoxColumn),typeof(DataGridTemplateColumn));
builder.AddCustomAttributes("Columns", attr);

这里通过把元数据添加到元数据存储区的方式来实现,当然你也可以直接在属性上挂元数据,两种方法都可以,具体可以看第一篇的介绍.

2.格式化集合项属性

如上图,每个类型都配有不同的图标,这一功能需要NewItemFactory 来完成,称之为创建项的工厂,我理解为是格式化项.

NewItemFactory是一个抽象类,有三个虚方法

CreateInstance方法会在创建新实例时对该对象做一些业务逻辑的变更

GetDisplayName方法则获取显示的名称,如下图的DataGridTextColumn

GetImage方法则是获取显示的对象图标了,如下图左侧图标.

可以根据需要重写这三个方法.我们来看下DataGridColumnFactory是如何实现的.

internal class DataGridColumnFactory : NewItemFactory
{public override object CreateInstance(Type type) {DataGridColumn gridColumn = null;if (type.IsAssignableFrom(typeof(DataGridTemplateColumn))){ gridColumn = CreateTemplateColumn();} else {gridColumn = Activator.CreateInstance(type) as DataGridColumn;}if (gridColumn != null) {gridColumn.Header = "Header";}return gridColumn;}/// <summary>///     Create a Template column with a default cell and editing template /// </summary>private static DataGridTemplateColumn CreateTemplateColumn() {DataGridTemplateColumn gridColumn = new DataGridTemplateColumn();gridColumn.CellTemplate = new DataTemplate();gridColumn.CellEditingTemplate = new DataTemplate();return gridColumn;}public override object GetImage(Type type, Size desiredSize) {object image = base.GetImage(type, desiredSize);if (typeof(DataGridTextColumn).IsAssignableFrom(type)) { image = Util.GetImage("DataGridTextColumn.png", desiredSize);} else if (typeof(DataGridHyperlinkColumn).IsAssignableFrom(type)) {image = Util.GetImage("DataGridHyperlinkColumn.png", desiredSize);} else if (typeof(DataGridComboBoxColumn).IsAssignableFrom(type)) {image = Util.GetImage("DataGridComboBoxColumn.png", desiredSize);} else if (typeof(DataGridCheckBoxColumn).IsAssignableFrom(type)) {image = Util.GetImage("DataGridCheckBoxColumn.png", desiredSize);} else if (typeof(DataGridTemplateColumn).IsAssignableFrom(type)) {image = Util.GetImage("DataGridTemplateColumn.png", desiredSize);}return image;}
}

以上代码应该很容易理解.定义好这个工厂类以后则需要用NewItemTypesAttribute中的FactoryType属性指定这个类型.现在刚开始的代码变更如下

NewItemTypesAttribute attr = new NewItemTypesAttribute(typeof(DataGridTextColumn),typeof(DataGridCheckBoxColumn),typeof(DataGridHyperlinkColumn),typeof(DataGridComboBoxColumn),typeof(DataGridTemplateColumn));
attr.FactoryType = typeof(DataGridColumnFactory);
builder.AddCustomAttributes("Columns", attr);

上下文菜单项

在我们使用wpf的datagird时候,在选中DataGrid控件时,点击右键的话,会有一个自定义的DataGrid菜单,如下图

wpf设计器允许对控件提供自定义菜单项,这是通过继承一个名为PrimarySelectionContextMenuProvider的类实现的,上图的右键菜单由DataGridMenuProvider来实现,我们来看一下具体实现方法.如下

1.声明一个MenuGroup类,表明一个菜单项组,一个菜单则是一个MenuAction类.

通过MenuGroup的Items集合添加MenuAction.

2.更新菜单项状态UpdateItemStatus ,该事件会都目前的菜单进行判断,做出状态变更,如初始化并未显示Remove Columns这个菜单.

public DataGridMenuProvider()
{// Set up the MenuGroup which holds the MenuAction items.MenuGroup dataOperationsGroup = new MenuGroup("DataGroup", "DataGrid");isDatasourceSetMenuAction = new MenuAction("You need to set ItemsSource to enable some column operations.");generateStockColumnsMenuAction = new MenuAction("Generate Columns");generateStockColumnsMenuAction.Execute += new EventHandler<MenuActionEventArgs>(GenerateStockColumnsMenuAction_Execute);addColumnsMenuAction = new MenuAction("Add/Edit Columns...");addColumnsMenuAction.Execute += new EventHandler<MenuActionEventArgs>(AddColumnsMenuAction_Execute);removeColumnsMenuAction = new MenuAction("Remove Columns");removeColumnsMenuAction.Execute += new EventHandler<MenuActionEventArgs>(RemoveColumnsMenuAction_Execute);dataOperationsGroup.HasDropDown = true;dataOperationsGroup.Items.Add(isDatasourceSetMenuAction);dataOperationsGroup.Items.Add(generateStockColumnsMenuAction);dataOperationsGroup.Items.Add(addColumnsMenuAction);dataOperationsGroup.Items.Add(removeColumnsMenuAction);this.Items.Add(dataOperationsGroup);        // Can have groups - show up as sub menus// The UpdateItemStatus event is raised immediately before // the menu show, which provides the opportunity to set states.UpdateItemStatus += new EventHandler<MenuActionEventArgs>(DataGridMenuProvider_UpdateItemStatus);
}

MenuAction可以通过Execute事件触发点击事件.这就可以使得运行时控件与设计器之间进行交互,这里涉及到一个wpf设计时的编辑模型放到下篇细讲.这篇就介绍集合项属性和自定义控件右键菜单的方法.下篇将会整理一个源码一起放上.

wpf控件设计时支持(2)相关推荐

  1. wpf控件设计时支持(1)

    wpf控件设计时支持(1) 原文:wpf控件设计时支持(1) 这部分内容几乎是大家忽略的内容,我想还是来介绍一下. 本篇源码下载 1.属性元数据 在vs IDE中,在asp.net,winfrom等开 ...

  2. wpf控件设计时支持(3)

    wpf设计时调试 编辑模型 装饰器 1.wpf设计时调试 为了更好的了解wpf设计时框架,那么调试则非常重要,通过以下配置可以调试控件的设计时代码 (1)将启动项目配置成外部的visual studi ...

  3. WPF 控件设计艺术[开篇]

    WPF 控件设计艺术--样式.模板.触发器.数据绑定 WPF 控件设计艺术--样式.模板.触发器.数据绑定:围绕WPF控件设计,从样式.模板.触发器和数据绑定触发,引导初学者快速设计和使用WPF控件设 ...

  4. [转] 使用模板自定义 WPF 控件

      [转] 使用模板自定义 WPF 控件                                                                                 ...

  5. 开源WPF控件库-AdonisUI

    原文:https://github.com/benruehl/adonis-ui 翻译:沙漠尽头的狼(谷歌翻译加持) 用于 WPF 应用程序的轻量级 UI 工具包,提供经典和增强的 Windows 视 ...

  6. WPF控件开发之自定义控件(3)

    创建 UserControl 如前所述,在 WPF 中创建控件的最简单方法是从 UserControl 派生.下面的示例演示用于定义 NumericUpDownUserControl 的 用户界面 ( ...

  7. 第一章:初识WPF,XAML,WPF控件

    前言 总目录 本章主要介绍WPF与XAML,以及WPF的控件的基本使用,让大家先初步认识WPF. 关于WPF的官方资料:官方WPF文档1 .官方WPF文档2.官方WPF文档3.官方WPF文档4 一.W ...

  8. 日志查看器:显示日志记录信息的快速WPF控件

    对于长时间运行的后台任务,用户了解当前执行的步骤很有帮助.LogViewer可以安全地多线程收集此信息,并将其显示为可滚动文本.LogViewer允许后台线程在不使用任何WPF代码的情况下写入格式化文 ...

  9. DevExpress v15.1:WPF控件升级(四)

    2019独角兽企业重金招聘Python工程师标准>>> <下载最新版DevExpress WPF Controls v15.1.5> WPF编辑器 在Token编辑器中的 ...

最新文章

  1. html5插件教程,HTML5教程 | HTML5 time元素
  2. Python程序全局观--以温度转换为例
  3. HashMap 的设置值,取值,遍历等
  4. 循环链表C/C++实现(数据结构严蔚敏版)
  5. php开发问题及解决方案,PHP开源开发框架ZendFramework使用中常见问题说明及解决方案...
  6. 23种设计模式C++源码与UML实现--解释模型
  7. 是否要入坑强化学习,看了这篇文章再说
  8. c# MEF框架(二 MEF的导出(Export)和导入(Import))
  9. 计算机不能辨别汉字wifi,Win10系统连接不上被隐藏的中文Wifi的解决方法
  10. 傍腾讯,切阿里,拼多多的千亿瞒天术
  11. 学Python必须背的42个常见单词
  12. 错误记录:自己创建activity时不能进行真机usb安装调试
  13. Spring boot整合shiro权限管理
  14. es6 混合commjs_Webpack打包ES6和CommonJs混合React
  15. 端口镜像 流量过滤_在 AWS 云环境中滥用 VPC 流量镜像抓取网络流量
  16. 初学“深入浅出MFC”之零篇
  17. 移动端h5不支持font-family里面的楷体、微软雅黑等字体
  18. 设备综合效率(OEE)的计算方法
  19. 读文献--《U-Net: Convolution Networks for Biomedical Image Segmentation 》
  20. 戴尔微型计算机主机怎么拆,微型主机 Dell OptiPlex 3020M 简单开箱

热门文章

  1. 关于javascript:void(0);,herf=”#”以及在IE6下,click事件失效的问题
  2. 澳洲留学征文活动获奖情况公布
  3. nodejs繁琐地自建路由
  4. 如何解决2012年7月1日增加闰秒后引起linux系统重启问题
  5. 第一次使用Android Studio时你应该知道的一切配置(三):gradle项目构建
  6. javascript的数值范围
  7. linux nfs搭建
  8. [泰然翻译] cocos2d programming guide 场景和菜单
  9. Myisamchk小工具使用手册
  10. MYSQL外键(Foreign Key)的使用