(一)、使用默认DataGridView
在上一篇中,小菜使用DataGridView控件来显示任务数据Tasks。用到的代码如下:
小菜之智能客户端(6)演化TaskVision,自定义DataGrid控件dgTasks.DataSource = _dataLayer.Tasks.DefaultView;
dgTasks为DataGridView控件。
效果如下图:
 小菜之智能客户端(6)演化TaskVision,自定义DataGrid控件
右边的dgTasks控件将强类型DataSet:DataSetTasks中的所有列都显示出来。因为这是默认情况。

(二)、使用默认DataGrid
vs2005的工具箱中只有DataGridView没有DataGrid,是不是就说DataGridView替代了DataGrid了。
那小菜在工具箱中找到DataGrid,那是不是说DataGrid替代DataGridView。

DataGridView可以替代DataGrid,一定是在哪些方面增强了。那是哪些地方呢?
如果你连DataGrid都没用过,也在相掺和说DataGridView替代DataGrid,那真该反思了。

上面的四句话,就是小菜从DataGrid说起的原因。

在vs2005中可以右击工具箱,选择项:
小菜之智能客户端(6)演化TaskVision,自定义DataGrid控件
将这一项勾选,确定后在工具箱就会看到DataGrid控件了,和自定义控件的添加方式类似。

那我们就用DataGrid替换DataGridView来看看效果,如下图:
小菜之智能客户端(6)演化TaskVision,自定义DataGrid控件
代码:
小菜之智能客户端(6)演化TaskVision,自定义DataGrid控件dgTasks.DataSource = _dataLayer.Tasks.DefaultView;
dgTasks为DataGrid控件。

效果和使用DataGridView差不多,不过DataGrid多了篮色的头部。
同样,右边的dgTasks控件也是将强类型DataSet:DataSetTasks中的所有列都显示出来。因为这是默认情况。

(三)、使用自定义DataGrid
上面的视觉效果一定让你很不满意吧。

头顶篮色鸡冠小菜可不想要,把所有列都显示出来小菜可不想要,列名直接是数据库中的字段小菜也不想要,添加删除修改也不是小菜想要的。

这些需求很常见,那怎么办呢?

(1)修改列标题
效果如下:
小菜之智能客户端(6)演化TaskVision,自定义DataGrid控件
哇!看起来不错噢。

小菜先给出代码,然后再分析:
创建一个类MainFormDgStyle:
小菜之智能客户端(6)演化TaskVision,自定义DataGrid控件using System;
小菜之智能客户端(6)演化TaskVision,自定义DataGrid控件
using System.Windows.Forms;
小菜之智能客户端(6)演化TaskVision,自定义DataGrid控件
小菜之智能客户端(6)演化TaskVision,自定义DataGrid控件
namespace TaskVision
主窗体中使用:
小菜之智能客户端(6)演化TaskVision,自定义DataGrid控件dgTasks.TableStyles.Add(MainFormDgStyle.GetStyle()); 
小菜之智能客户端(6)演化TaskVision,自定义DataGrid控件dgTasks.DataSource 
= _dataLayer.Tasks.DefaultView;
我们来分析下代码:
DataGrid->DataGridTableStyle->DataGridColumnStyle

DataGridTableStyle为DataGrid表格样式。
DataGridColumnStyle为DataGrid列样式,为抽象类。
DataGridTextBoxColumn(为DataGrid文本框列样式) 继承 DataGridColumnStyle
DataGridBoolColumn(为DataGrid单选框列样式) 继承 DataGridColumnStyle

所以下面的代码就很好理解了。
DataGridTextBoxColumn taskID = new DataGridTextBoxColumn();
taskID.HeaderText = "ID";  //列标头的文本
taskID.MappingName = "TaskID";  //该列样式所映射到的数据成员名称
taskID.Width = 30;  //列宽度

其它的都一样了。

dgTableStyle.GridColumnStyles.AddRange( new DataGridColumnStyle[]{ taskID,priorityText,等等});
这是简单的把所定义的列样式添加到DataGrid表格样式中。

dgTableStyle.MappingName = TableName; //指定映射到数据源的名称

好了,继续我们的改进DataGrid控件。
我们希望默认情况下DataGrid中Date Created和Last Changed这两列不显示,不过经过定制可以显示出来。
这样我们可以修改代码将这两列的宽度暂时定为0,这样就可以暂时不显示出来,以后还有显示出来的机会。
小菜之智能客户端(6)演化TaskVision,自定义DataGrid控件DataGridTextBoxColumn dateCreated = new DataGridTextBoxColumn();
小菜之智能客户端(6)演化TaskVision,自定义DataGrid控件dateCreated.HeaderText 
= "Date Created";
小菜之智能客户端(6)演化TaskVision,自定义DataGrid控件dateCreated.MappingName 
= "DateCreated";
小菜之智能客户端(6)演化TaskVision,自定义DataGrid控件dateCreated.Width 
= 0;
小菜之智能客户端(6)演化TaskVision,自定义DataGrid控件
小菜之智能客户端(6)演化TaskVision,自定义DataGrid控件DataGridTextBoxColumn dateModified 
= new DataGridTextBoxColumn();
小菜之智能客户端(6)演化TaskVision,自定义DataGrid控件dateModified.HeaderText 
= "Last Changed";
小菜之智能客户端(6)演化TaskVision,自定义DataGrid控件dateModified.MappingName 
= "DateModified";
小菜之智能客户端(6)演化TaskVision,自定义DataGrid控件dateModified.Width 
= 0
(2)美化DataGrid
让DataGrid隔行显示背景色:
小菜之智能客户端(6)演化TaskVision,自定义DataGrid控件dgTableStyle.AlternatingBackColor = System.Drawing.Color.LemonChiffon;
运行效果如下图:
小菜之智能客户端(6)演化TaskVision,自定义DataGrid控件 
 
ID列左边的行标头,小菜并不想要,能去掉吗,当然。
小菜之智能客户端(6)演化TaskVision,自定义DataGrid控件dgTableStyle.RowHeadersVisible = false;
运行效果如下图:
小菜之智能客户端(6)演化TaskVision,自定义DataGrid控件 
去掉DataGrid的篮色鸡冠:
可以在dgTasks的属性窗口将CaptionVisible设为false
对应代码dgTasks.CaptionVisible = false;
运行效果如下:
小菜之智能客户端(6)演化TaskVision,自定义DataGrid控件 

从上图你可以看出,DataGrid默认使用DataGridTextBoxColumn做为列样式,所以默认是可编辑数据,最后一行白色可以允许你添加数据,
怎样才能禁止DataGrid添加删除修改呢?
在dgTasks的属性窗口将ReadOnly设为true
对应代码dgTasks.ReadOnly = true;
小菜之智能客户端(6)演化TaskVision,自定义DataGrid控件
从图中你也可以看出,现在不能编辑,添加数据了,为灰色底框。

(3)自定义DataGrid列
新的需求出来了:Progress列是显示任务进度的,使用数字表示不够直观,让我们使用进度条来显示它。
如下图:
小菜之智能客户端(6)演化TaskVision,自定义DataGrid控件
我们之前是使用:DataGridTextBoxColumn
小菜之智能客户端(6)演化TaskVision,自定义DataGrid控件DataGridTextBoxColumn progressText = new DataGridTextBoxColumn();
小菜之智能客户端(6)演化TaskVision,自定义DataGrid控件progressText.HeaderText 
= "Progress";
小菜之智能客户端(6)演化TaskVision,自定义DataGrid控件progressText.MappingName 
= "Progress";
小菜之智能客户端(6)演化TaskVision,自定义DataGrid控件progressText.Width 
= 55;
我们要自定义出进度条的效果,可以自定义类DataGridProgressBarColumn 继承 DataGridTextBoxColumn
为何不继承至DataGridColumnStyle呢?因为继承DataGridTextBoxColumn我们的工作将简化很多。这像写控件,你不会都想从Component继承吧,同理。
小菜之智能客户端(6)演化TaskVision,自定义DataGrid控件using System;
小菜之智能客户端(6)演化TaskVision,自定义DataGrid控件
using System.Drawing;
小菜之智能客户端(6)演化TaskVision,自定义DataGrid控件
using System.Windows.Forms;
小菜之智能客户端(6)演化TaskVision,自定义DataGrid控件
小菜之智能客户端(6)演化TaskVision,自定义DataGrid控件
namespace TaskVision
}
这样我们在MainFormDgStyle.cs中就可以将
小菜之智能客户端(6)演化TaskVision,自定义DataGrid控件DataGridTextBoxColumn progressText = new DataGridTextBoxColumn();
小菜之智能客户端(6)演化TaskVision,自定义DataGrid控件progressText.HeaderText 
= "Progress";
小菜之智能客户端(6)演化TaskVision,自定义DataGrid控件progressText.MappingName 
= "Progress";
小菜之智能客户端(6)演化TaskVision,自定义DataGrid控件progressText.Width 
= 55;
修改为:
小菜之智能客户端(6)演化TaskVision,自定义DataGrid控件DataGridProgressBarColumn progressText = new DataGridProgressBarColumn("Progress""Progress"55);
代码并不复杂,我们可查询.net sdk2.0关于Paint的参数,注意是查询DataGridColumnStyle.Paint,为什么不是DataGridTextBoxColumn.Paint呢?因为我们想要得到更多的支持,像背景刷Brush backBrush, 前景刷Brush foreBrush。
还有就是Edit,也是使用DataGridColumnStyle.Edit,这样才能保证无法编辑。

DataGridColumnStyle.Paint参数如下:
g:要绘制到的 Graphics。
bounds:要在其中绘画的外围 Rectangle。
source:该列所属的 System.Windows.Forms.DataGrid 控件的 CurrencyManager
rowNum:所引用的基础数据表中的行号。
backBrush:用于绘制背景色的 Brush。
foreBrush:用于绘制前景色的 Color。
alignToRight:一个值,它指示内容是否为右对齐。如果内容为右对齐,则为 true;否则为 false

同样我们也不希望其它列可以编辑,因为灰色的底框太难看了,我们希望的效果如下图:
小菜之智能客户端(6)演化TaskVision,自定义DataGrid控件 
那我们就新建一个DataGridTextBoxColumn继承至DataGridTextBoxColumn
小菜之智能客户端(6)演化TaskVision,自定义DataGrid控件using System;
小菜之智能客户端(6)演化TaskVision,自定义DataGrid控件
using System.Drawing;
小菜之智能客户端(6)演化TaskVision,自定义DataGrid控件
using System.Windows.Forms;
小菜之智能客户端(6)演化TaskVision,自定义DataGrid控件
using System.Threading;
小菜之智能客户端(6)演化TaskVision,自定义DataGrid控件
小菜之智能客户端(6)演化TaskVision,自定义DataGrid控件
namespace TaskVision
接下来就修改下MainFormDgStyle中的GetStyle()
将非日期的列按如下方式修改
小菜之智能客户端(6)演化TaskVision,自定义DataGrid控件DataGridTextBoxColumn taskID = new DataGridTextBoxColumn();
小菜之智能客户端(6)演化TaskVision,自定义DataGrid控件taskID.HeaderText 
= "ID";
小菜之智能客户端(6)演化TaskVision,自定义DataGrid控件taskID.MappingName 
= "TaskID";
小菜之智能客户端(6)演化TaskVision,自定义DataGrid控件taskID.Width 
= 30;
修改为
小菜之智能客户端(6)演化TaskVision,自定义DataGrid控件DataGridTextBoxColumn taskID = new DataGridTextBoxColumn(string.Empty, "ID""TaskID"30);
将日期的列按如下方式修改
小菜之智能客户端(6)演化TaskVision,自定义DataGrid控件DataGridTextBoxColumn dateDue = new DataGridTextBoxColumn();
小菜之智能客户端(6)演化TaskVision,自定义DataGrid控件dateDue.HeaderText 
= "Due Date";
小菜之智能客户端(6)演化TaskVision,自定义DataGrid控件dateDue.MappingName 
= "DateDue";
小菜之智能客户端(6)演化TaskVision,自定义DataGrid控件dateDue.Width 
= 65;
小菜之智能客户端(6)演化TaskVision,自定义DataGrid控件
修改为
小菜之智能客户端(6)演化TaskVision,自定义DataGrid控件DataGridTextBoxColumn dateDue = new DataGridTextBoxColumn("d""Due Date""DateDue"65);
DataDue为任务预计完成日期,如果超期,应该给于强调,比如让日期显示为红色。
我们可以修改DataGridTextBoxColumn来完成这个功能:
小菜之智能客户端(6)演化TaskVision,自定义DataGrid控件using System;
小菜之智能客户端(6)演化TaskVision,自定义DataGrid控件
using System.Drawing;
小菜之智能客户端(6)演化TaskVision,自定义DataGrid控件
using System.Windows.Forms;
小菜之智能客户端(6)演化TaskVision,自定义DataGrid控件
using System.Threading;
小菜之智能客户端(6)演化TaskVision,自定义DataGrid控件
小菜之智能客户端(6)演化TaskVision,自定义DataGrid控件
namespace TaskVision
上面的优先级Priority使用文本显示:Major(高),Medium(中),Minor(低)不太直观,让我们使用图片来显示,这样可以引起注意。Major使用:Major.gif小菜之智能客户端(6)演化TaskVision,自定义DataGrid控件,Medium使用:Medium.gif空白图片,Minor使用:Minor.gif 小菜之智能客户端(6)演化TaskVision,自定义DataGrid控件
最终效果如下图:
小菜之智能客户端(6)演化TaskVision,自定义DataGrid控件 
我们为优先级定义一个列DataGridPriorityColumn代码如下:
小菜之智能客户端(6)演化TaskVision,自定义DataGrid控件using System;
小菜之智能客户端(6)演化TaskVision,自定义DataGrid控件
using System.Drawing;
小菜之智能客户端(6)演化TaskVision,自定义DataGrid控件
using System.Collections;
小菜之智能客户端(6)演化TaskVision,自定义DataGrid控件
using System.Windows.Forms;
小菜之智能客户端(6)演化TaskVision,自定义DataGrid控件
小菜之智能客户端(6)演化TaskVision,自定义DataGrid控件
namespace TaskVision
修改MainFormDgStyle的代码:
小菜之智能客户端(6)演化TaskVision,自定义DataGrid控件DataGridTextBoxColumn priorityText = new DataGridTextBoxColumn("Priority","PriorityText",75);
修改为:
小菜之智能客户端(6)演化TaskVision,自定义DataGrid控件DataGridPriorityColumn priorityText = new DataGridPriorityColumn("Priority""PriorityText"15);
好了,到现在自定义DataGrid就演化完了。

提供到该篇为止的完整源码,包括数据库:https://files.cnblogs.com/a-peng/taskvision_6.rar

相关文章: