【全面解禁!真正的Expression Blend实战开发技巧】第七章 MVVM初体验-在DataGrid行末添加按钮
原文:【全面解禁!真正的Expression Blend实战开发技巧】第七章 MVVM初体验-在DataGrid行末添加按钮
博客更新较慢,先向各位读者说声抱歉。这一节讲解的依然是开发中经常遇到的一种需求,在DataGrid行末添加按钮。请看下图。

上图中"功能"这一列里显示的并不是数据,而是一个TextButton。当点击它时,对应的进行删除操作。这里为了大家看的明显果,我在点击按钮后,弹出当前选中行的"Name"属性。当然你也可以对行内数据进行增删改查等各种操作。除此之外,他还可以充分适应分辨率及IE大小。

上图中,当IE缩小到一定程度后,DataGrid会自动产生水平滚动条,只要向右边拖,就可以看到我们的删除按钮。看起来本来就应该是这样不是么?但实际的情况中,我见过的一些项目的做法往往都是错误的,他们不能自适应IE大小,当IE宽度缩短时,删除按钮就消失了。错误的效果,如下图所示.

上图中是错误的做法,当IE窗口缩小后,即使滚动条拖到最右边,依然看不到删除按钮。并且,删除这一列不能显示列名。
这次的课程可能稍微复杂,涉及到后台代码,及一些MVVM的手法。但请相信我,熟练掌握后,实现这样的DataGrid,3分钟足够了。好了,不废话了,请大家打开Blend,一起跟我做。首先新建一个项目,拖拽一个DataGrid到你的LayoutRoot中。然后新建一个示例数据源,如下图所示:(关于如何新建示例数据源,请参考: 第六章 认识ListBox)

上图中我们的示例数据源只有两个属性,number型的Age和String型的Name。接下来,请直接拖拽Collection节点到DataGrid上。如果你操作完全正确,会得到下图中的效果。

接下来,在Object an TimeLine面板中,展开DataGrid节点,可以看到两个DataGridTextColumn,如果你把Name拖到Age上面,DataGrid的列就是按"Name"->"Age"的顺序显示。

你还可以通过修改它们的Header属性,将英文"Age","Name"变成"年龄","姓名",

接下来,请点击属性面板左侧的
按钮,切换到代码和设计视图。

随后你可以看到DataGrid的代码是这样的.

接下来需要手写一段代码。
<sdk:DataGridTemplateColumn Header="功能"/>
将这段代码写在两个DataGridTextColumn后面。

然后,先不要急着运行程序,此时运行会提示一个错误,"DataGridTemplateColumn必须指定一个Template"。所以,我们还需要为它定义一个模板。
在Object and Timeline面板中,右击我们新建的列,在弹出菜单中选择Edit Column Templates->Edit CellTemplate->Create Empty

在弹出面板中为模板取一个名字,然后点击OK按钮会进入模板编辑视图,如下图所示。

接下来,只需要在这个Grid中添加一个按钮即可,在Demo中我使用的是TextButton。(关于TextButton的做法,请参考: 第三章 从最常用ButtonStyle开始 - TextButton),然后结束编辑,退出模板编辑视图。我们可以看到一个TextButton已经被正确的植入DataGrid。

看起来很不错不是么?不过现在这个删除按钮还不能响应任何事件,接下来来我们需要一些真正的Coding工作。使用MVVM的手法彻底分离UI和Code,并调用按钮的点击事件,弹出当前选中行的信息。
首先请在Project菜单中右击解决方案节点,在弹出菜单中选择Edit in Visual Studio。下面的coding工作会在VS2010中进行。讲到这里有人可能会问,“Blend不是也可以写代码么?为什么还要打开VS?” 这里我多说一嘴,Blend在设计方面的能力是毋庸置疑的,但coding还是要用VS,相信我不要用Blend写任何C#或VB编码,Blend弱智且低能的语法提示会恶心死你。

在VS中,新建一个Class,名为MyCommand。

MyCommand中的代码如下,大家可以直接拷贝。
public class MyCommand
{
public ICommand ShowInfoCommand
{
get;
private set;
}
public MyCommand()
{
this.ShowInfoCommand = new ActionCommand(this.ShowInfo);
}
private void ShowInfo(object selectedItem)
{
Expression.Blend.SampleData.SampleDataSource.Item item = selectedItem as Expression.Blend.SampleData.SampleDataSource.Item;
MessageBox.Show(item.Name.ToString());
}
}
如果你在为ActionCommand添加引用的时候,提示找不到这个类型。请引用
后再试。接下来,F6编译一下工程,编译通过后用Vs打开我们刚才编辑的Xaml,在UserControl标签中输入下面代码。(注意此处的Lession7是我自己项目的命名空间名,此处你需要将它替换为你自己的项目命名空间名。)
xmlns:local="clr-namespace:Lession7"。
接着在UserControl.Resources标签中输入下面代码。
<local:MyCommand x:Key="MyCommand" d:IsDataSource="false"/>
输入后的效果如下图所示。

然后再VS中按Ctrl+F,弹出搜索菜单,搜索关键字“删除”。注意,搜索范围是CurrentDocument,而不是整个解决方案。然后你可以定位到刚才我们在DataGrid中添加的哪个删除按钮。

把下面代码添加到“删除”按钮中。
Command="{Binding ShowInfoCommand, Mode=OneWay,Source={StaticResource MyCommand}}" CommandParameter="{Binding Mode=OneWay}"
添加后的效果如下图所示

点击F5运行程序,恭喜各位,大功告成!

背后的故事:
本章中涉及的知识较多,如果你是一个美工或者设计人员。可能会感觉只是照着做出来了,但很多原理都不懂。下面我简单对一些关键点做讲解。
在MyCommand类中,我们定义了一个名为ShowInfoCommand。因为他是一个“指令”,所以我们可以将它与任何控件的点击事件进行捆绑。本章中就将它捆绑到了“删除”按钮上。在ShowInfo(object selectedItem)方法中,我们通过强制转换selectedItem,得到了当前选中行的内容。本例中因为使用的示例数据源,所以用的是Expression.Blend.SampleData.SampleDataSource.Item类型。在实际项目中,你需要将它换位DataGrid数据源的实际类型。
如何将MyCommand与Xaml中的Button绑定?
第一步在Xaml中定义关于MyCommand的引用。代码是:xmlns:local="clr-namespace:Lession7" ,注意"Lession7"是项目命名空间名。
第二步在UserControl.Resource标签中声明一个xaml可以引用的对象。代码是<local:MyCommand x:Key="MyCommand" d:IsDataSource="false"/>
“d:IsDataSource="false"“标识我们声明的不是一个数据源。这个信息主要是给Blend用的,不是必须的。
第三步就是在“删除”按钮中写的那段代码了,将Button的Command属性与我们声明的MyCommadn绑定。
项目源码下载地址http://files.cnblogs.com/kaodigua/Lession7.rar
博客我会坚持写,只是更新时间不一定。有空了我一定会连续更新。希望大家一直支持我。如果你喜欢我的文章,请点一下文章右下角的“推荐”,谢谢。
【全面解禁!真正的Expression Blend实战开发技巧】第七章 MVVM初体验-在DataGrid行末添加按钮的更多相关文章
- 【全面解禁!真正的Expression Blend实战开发技巧】十一章 全面解析布局(Grid & Canvas &StackPanel &Wrappanel)
原文:[全面解禁!真正的Expression Blend实战开发技巧]十一章 全面解析布局(Grid & Canvas &StackPanel &Wrappanel) 写这篇文 ...
- 【全面解禁!真正的Expression Blend实战开发技巧】第九章 FluidMoveBehavior完全解析之二平滑运动的滚动条
原文:[全面解禁!真正的Expression Blend实战开发技巧]第九章 FluidMoveBehavior完全解析之二平滑运动的滚动条 这一章讲解FluidMoveBehavior的另一个应用, ...
- 【全面解禁!真正的Expression Blend实战开发技巧】第二章 你好,UI设计师
原文:[全面解禁!真正的Expression Blend实战开发技巧]第二章 你好,UI设计师 你好,UI设计师 曾几何时我从没想过要与艺术家打交道,但是Silverlight改变了这一切.UI设计师 ...
- 【全面解禁!真正的Expression Blend实战开发技巧】第一章 真正的开发中的最佳的做法
原文:[全面解禁!真正的Expression Blend实战开发技巧]第一章 真正的开发中的最佳的做法 从设计者到开发者 设计师创建一个应用程序的布局然后让开发者去实现. 从开发者到设计者 开发者创建 ...
- 【全面解禁!真正的Expression Blend实战开发技巧】序章
原文:[全面解禁!真正的Expression Blend实战开发技巧]序章 从silverlight2开始我也和大家一样一直在跟随微软的脚步,从sl2~sl4一步一步过来,总结了不少心得体会.由于各种 ...
- 【全面解禁!真正的Expression Blend实战开发技巧】第十章 FluidMoveBehavior完全解析之三飞出ListBox吧
原文:[全面解禁!真正的Expression Blend实战开发技巧]第十章 FluidMoveBehavior完全解析之三飞出ListBox吧 刚才有人说我的标题很给力,哈哈.那这个标题肯定更给力了 ...
- 【全面解禁!真正的Expression Blend实战开发技巧】第八章 FluidMoveBehavior完全解析之一漂浮移动
原文:[全面解禁!真正的Expression Blend实战开发技巧]第八章 FluidMoveBehavior完全解析之一漂浮移动 好久没更新博客了,今天如果没急事,准备连发三篇,完全讲解Blend ...
- 【全面解禁!真正的Expression Blend实战开发技巧】第四章 从最常用ButtonStyle开始 - PathButton
原文:[全面解禁!真正的Expression Blend实战开发技巧]第四章 从最常用ButtonStyle开始 - PathButton 上一篇我们介绍了TextButton,但为了追求界面的张力, ...
- 【全面解禁!真正的Expression Blend实战开发技巧】第五章 从最常用ButtonStyle开始 - ImageButton
原文:[全面解禁!真正的Expression Blend实战开发技巧]第五章 从最常用ButtonStyle开始 - ImageButton 本章围绕ImageButton深入讨论,为什么是Image ...
随机推荐
- 从 BM 到 RBM
1. 拓扑结构上 如下图示,在拓扑结构上,RBM(受限的玻尔兹曼机)与 BM(玻尔兹曼机)的最大区别在于: RBM 取消了可见层的层内连接以及隐含层的层内连接,主要在于 BM 的层内连接使得其学习过程 ...
- 数据库基本查询语句(SQL常用增删改查语句 简单复习 mark)
SQL常用增删改查语句 1增 1.1[插入单行]insert [into] <表名> (列名) values (列值)例:insert into Strdents (姓名,性别,出生日期) ...
- 【t080】遗址
Time Limit: 1 second Memory Limit: 128 MB [问题描述] 很久很久以前有一座寺庙,从上往下看寺庙的形状正好是一个正方形,在4个角上竖立着圆柱搭建而成.现在圆柱都 ...
- java-线程-ABCABC
public class OneByOne { private Lock lock = new ReentrantLock(); private Condition conditionA = lock ...
- 亲测有效,解决Can 't connect to local MySQL server through socket '/tmp/mysql.sock '(2) ";
版权声明:本文为博主原创文章,未经博主允许不得转载. https://blog.csdn.net/hjf161105/article/details/78850658 最近租了一个阿里云云翼服务器,趁 ...
- 重装huson遇到的一些错误及解决
作者:朱金灿 来源:http://blog.csdn.net/clever101 服务器换了一块新硬盘,拷贝回原来的数据后结果发现Apache tomcat服务不能启动了,错误提示是:本地计算机上的A ...
- Azure Messaging-ServiceBus Messaging
Azure Messaging-ServiceBus Messaging 上篇博文中我们介绍了Azure Messaging的重复消息机制.At most once 和At least once. A ...
- numpy 下的数据结构与数据类型的转换(np.array vs. np.asarray)
1. np.asarray -- numpy 风格的类型转换 从已有多维数组创建新的多维数组,数据类型可重新设置 >> B = np.asarray(A, dtype='int32') 2 ...
- CUDA页锁定内存(Pinned Memory)
对CUDA架构而言,主机端的内存被分为两种,一种是可分页内存(pageable memroy)和页锁定内存(page-lock或 pinned).可分页内存是由操作系统API malloc()在主机上 ...
- 放大缩小,只需要使用这2个函数:SetWindowExtEx、SetViewportExtEx
相似函数: ScaleWindowExtEx.ScaleViewportExtEx 本例效果图: 代码文件: unit Unit1; interface uses Windows, Message ...