原文: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控件设计时支持(3)

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

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

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

  3. WPF解决按钮上被透明控件遮盖时无法点击问题

    原文:WPF解决按钮上被透明控件遮盖时无法点击问题 IsHitTestVisible="False" 在控件上设置如上属性即可,即可让透明控件不触发点击效果

  4. 基于WPF系统框架设计(10)-分页控件设计

    背景 最近要求项目组成员开发一个通用的分页组件,要求是这个组件简单易用,通用性,兼容现有框架MVVM模式,可是最后给我提交的成果勉强能够用,却欠少灵活性和框架兼容性. 设计的基本思想 传入数据源,总页 ...

  5. WPF控件获得焦点时去除虚线框

    原文:WPF控件获得焦点时去除虚线框 <Setter Property="FocusVisualStyle" Value="{x:Null}" />

  6. 浅尝辄止——使用ActiveX装载WPF控件

    1 引言 使用VC编写的容器类编辑器,很多都可以挂接ActiveX控件,因为基于COM的ActiveX控件不仅封装性不错,还可以显示一些不错的界面图元. 但是随着技术不断的进步,已被抛弃的Active ...

  7. 反爬虫:利用ASP.NET MVC的Filter和缓存(入坑出坑) C#中缓存的使用 C#操作redis WPF 控件库——可拖动选项卡的TabControl 【Bootstrap系列】详解Bootstrap-table AutoFac event 和delegate的分别 常见的异步方式async 和 await C# Task用法 c#源码的执行过程

    反爬虫:利用ASP.NET MVC的Filter和缓存(入坑出坑)   背景介绍: 为了平衡社区成员的贡献和索取,一起帮引入了帮帮币.当用户积分(帮帮点)达到一定数额之后,就会“掉落”一定数量的“帮帮 ...

  8. 《Dotnet9》系列-开源C# WPF控件库3《HandyControl》强力推荐

    大家好,我是Dotnet9小编,一个从事dotnet开发8年+的程序员.我最近开始写dotnet分享文章,希望能让更多人看到dotnet的发展,了解更多dotnet技术,帮助dotnet程序员应用do ...

  9. WPF控件模板

    引言:在进行WPF项目开发过程中,由于项目的需要,经常要对某个控件进行特殊的设定,其中就牵涉到模板的相关方面的内容.本文也是在自己进行项目开发过程中遇到控件模板设定时集中搜集资料后整理出来的,以供在以 ...

随机推荐

  1. [Nuxt] Add CSS Libraries to Nuxt

    You can easily add CSS libraries to Nuxt using yarn or npm to install them, then simply adding them ...

  2. ZOJ 1101 Gamblers 二分

    http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemId=101 让你在一堆互不相同的数中查找是否有a=b+c+d,若有不同的解,则输出最大 ...

  3. 【5001】n皇后问题

    Time Limit: 10 second Memory Limit: 2 MB 在n*n的棋盘上放置n个皇后(国际象棋中的皇后,n≤10)而彼此不受攻击(即在棋盘的任一行,任一列和任一对角线上不能放 ...

  4. Mac OS X Kernel Basic User Credentials

    User Credentials In order to understand security in OS X, it is important to understand that there a ...

  5. [Node.js] Provide req.locals data though middleware

    We can create Template Helpers, which can contains some common reuseable data and libs. /* This is a ...

  6. php实现旋转数组的最小数字

    php实现旋转数组的最小数字 一.总结 1.题目描述定位法:掐准输入输出这两个关键词,然后题目意思就很清晰了 2.这个题目就是找数组的最小值 二.php实现旋转数组的最小数字 题目描述: 把一个数组最 ...

  7. text输入框改变事件

    前端页面开发的很多情况下都需要实时监听文本框输入,比如腾讯微博编写140字的微博时输入框hu9i动态显示还可以输入的字数.过去一般都使用onchange/onkeyup/onkeypress/onke ...

  8. POST提交数据时四种常见的数据格式

    最近项目部署到新环境tomcat+mysql,想看看项目部署成功没有,就用soupui调对应接口开测试,soupui使用比较简单,给上接口地址,入参xml报文,把入参的media Type设置为app ...

  9. Ubuntu su 认证失败

    在使用Ubuntu作为开发环境时经常须要在全局安装一些依赖框架等.这个时候就经常须要用到root权限.可是在Ubuntu下第一次使用su命令时会提示认证失败:查找资料后发现Ubuntu下root权限默 ...

  10. MySQL慢日志的相关参数

    slow-query-log = on #开启MySQL慢查询功能 slow_query_log_file = /data/mysql/testdb-slow.log #设置MySQL慢查询日志路径 ...