DevExpress 控件使用-不求精-不求顶-不求名-只求对您能有丝帮助

奋斗小丁哥 2015-06-02 10:07:20
加精
虽然不是一名职业开发人员,但也开发过一些项目。每次项目工期都非常紧张,而且都或多或少地需要一些没有学习过的技术,大家都知道一涉及到新技术就会遇到很多问题,有时对于过来人来说一些不是问题的问题,在新手面前很可能是一个拦路虎,进而影响项目进度耽误工期,解决方案很简单,就是打开百度或者google查资料,看看别人是不是也遇到过类似的问题,怎么解决的,什么解决方案。干过这么多项目,真心说得益于互联网的便利,得益于大家的分享!如果没有网络,没有那么多技术大Boss在网上的热心解答,无私的技术支持与分享,不惜自己宝贵休息时间的奉献精神(这句主要是为了拔高,见谅:)),我想我们的开发速度不会这么快,项目的进度也不会那么顺利。所以,每次从网上找到答案并顺利解决问题时,兴奋高兴之余,更是心怀感激,而且还会假设如果没有Boss们的技术贴,该怎么办呢,项目干不完就又不能睡觉了!每每此时,我都想着等这个项目结束了,一定要将项目中遇到的一些难点和一些开发经验发到网上和大家分享,可是项目一结束,就忙这忙那,一会这事一会那事,根本没有时间发帖,时间一长,项目中的技术、难点、经验也都忘的差不多了,也没有当时那种得到馈赠,想及时予以回报的心情了,最后也就不写了(有没有和我一样的技术男,请对号入座),其实这些都是借口,是一种自私的表现,自己用完了,怕耽误自己的时间,也就不管别人了,如果你想做,就一定能找到时间,所以我说这是一种自私的表现(个人意见,如有不同看法,但还请保持冷静)。
俗话说拿人手短,吃人嘴短!虽然之前一直没有到网上分享自己的经验,但内心也始终怀有一种自责之情。直到完成最近一个项目后,让我这种“短之情”达到了一种历史极值,迫使自己必须抽出时间分享一下不知是否能对后来人有所帮助的经历。这个项目是2014年10月底接手的,领导让我用C#进行开发,之前关于C#的经验较少,工期非常紧张,将近3个月(还有其他的工作要做,项目是一部分)。接到项目后,我做了一个DEMO,领导不太满意,界面不太美观,弹出窗体较多,不简洁,而且领导想要的“树表”(tree和grid控件的结合体)界面也没有实现(当时,是通过其他界面解决树表控件问题,但是界面不友好)。在我国,领导不满意,是一件非常大的事,千万不能掉以轻心,必须得引起重视。于是,日以继夜地找资料、找源码、找控件,最后找到两款控件一个是ComponentOne,另一个则是DevExpress,最后选择了DevExpress,个人认为后者的功能要强于前者(个人意见)。在DevExpress的支持下,我又重新做了Demo,show my boss,结果领导比较满意,于是快速地进入项目的业务实现阶段,这一过程更得益于网络分享,快速掌握该控件的使用方法,以及解决DevExpress使用过程中遇到的各种问题,进而非常顺利地完成了项目的开发。真心地感谢,分享这些技术的每一个人。所以,在这个项目结束的三个多月后,我重新打开开发环境,利用将近两天的时间,一点一点一步一步总结、整理关于这个控件的使用方法和经验。所以,不求精、不求顶、不求名,只求本人的一点愚见能为您的项目开发或者DevExpress学习带来一丝微薄之力,足以。
已经说了不少废话,言归正传。DevExpress和ComponentOne相比的话,我觉得DevExpress功能更加强大,有人说DevExpress速度慢,但用过之后发现,其带来的效率问题与程序本身的效率相比,可以忽略不计,所以DevExpress的效率不是问题。DevExpress是 Developer Express的缩写,DevExpress是一家全球知名的控件开发公司,生产很多产品,其中DXperience是一套关于.NET的用户界面控件套装(Winforms和Webforms),目前最全的版本的是DXperience Universal Subscription,简称DEV宇宙版。这个控件国内有代理,打算过段时间买一套最新的,也可以从老外那里买,差价估计在1-2W之间。本次项目开发采用的是DevExpress13.2.8,记不清是从官网上下的试用版,还是从网上随便找的,刚开始用的试用版,后来弄到了正版,但是可以破解,这个站上面就有破解程序,很容易的,而且没有必要弄更高的版本(高版本的貌似破解起来有难度,个人猜测),这个版本就可以完全满足winform类型的项目开发。本次需要分享的东西主要涉及两个控件的使用,一个树DevExpress.XtraTreeList,一个表格DevExpress.XtraGrid,这是两个功能非常强大的控件。
1. DevExpress.XtraTreeList控件
将其简称为tree,tree其实就是一个树表控件,他像树一样包含具有父子关系的若干节点,同时每个节点又是一个带有多个字段的记录。其用法非常简单方便,只需要为其配置带有父子关系的数据源,其就可以按照树的形式进行显示。
1.1 DevExpress.XtraTreeList配置数据源
数据源一般是一个二维表,可以是数据库中的表,该表中要包含表示父子关系的两个字段,即主键和父亲的主键。下面的代码是手动创建的数据源DataTable。
DataTable dtAllPath = new DataTable("dtAllPath");
dtAllPath.Columns.Add("nodeID", typeof(int));
dtAllPath.Columns.Add("parNodeID", typeof(int));
dtAllPath.Columns.Add("stateName", typeof(string));
dtAllPath.Columns.Add("stateCode", typeof(string));
dtAllPath.Columns.Add("condition", typeof(string));
dtAllPath.Rows.Add(new object[] { 1, 0, "1", "1", "" });
dtAllPath.Rows.Add(new object[] { 2, 0, "2", "2", "" });
dtAllPath.Rows.Add(new object[] { 3, 1, "1.1", "1.1", "" });
dtAllPath.Rows.Add(new object[] { 4, 2, "2.1", "2.1", "" });
treeList1.DataSource = dtAllPath;

上面的代码中,nodeID是每行记录的主键,parNodeID是每行记录的父亲记录的主键,0表示树的根结点。最后一行代码是将生成的数据源交给tree显示。当然为了完成树的显示工作,还需要配置tree的KeyFieldName属性为nodeID,ParentFieldName属性为parNodeID(选中tree,在vs的属性窗口设置),还需要为tree添加列并配置该列与数据源中的字段对应关系,右键tree控件选择run designer弹出下图,FieldName用来配置对应关系,tree中添加了两列,第一列和stateCode对应,designer可以配置tree的各种属性,列标题,cell中的字体颜色等等,不再一一赘述。

1.2 DevExpress.XtraTreeList添加checkbox
在tree的结点中添加checkbox是一项非常实用常见的功能,设置起来非常简单,选中tree,在VS的属性窗口中,找到OptionsView\ShowCheckBoxes,将其设置为true,即可。
1.3 DevExpress.XtraTreeList列表中添加ComboBox
在tree控件中直接对信息进行编辑,有时可能需要用到ComboBox控件,具体添加方法,右键/run designer/选择列/ColumnEdit/New,为该列创建一个内嵌的ComboBox控件,即repositoryItemComboBox,具体如下图所示。

1.4 repositoryItemComboBox下拉表不能显示
通过repositoryItemComboBox的click事件,向其动态add下拉列表中的items后,点击repositoryItemComboBox的下拉按钮,下拉列表闪一下就消失了(不是在click事件中添加items的情况,不会出现此问题)。解决方案,在repositoryItemComboBox的ButtonClick事件中,将事件源sender转换为ComboBoxEdit,再利用add函数添加item,最后手动显示下拉列表,代码如下:
ComboBoxEdit combo = sender as ComboBoxEdit; combo.Properties.Items.Add(…);
combo.ShowPopup();

1.5 DevExpress.XtraTreeList设置焦点函数setFocusedNode()无效
当使用TreeListNode addedNode = treeList1.AppendNode(参数略),向tree中添加一个节点后,一般想立刻使这个新添加的节点获得焦点,但此时如果直接使用treeList1.SetFocusedNode(addedNode)则无效,可能是因为addedNode中不包含tree为其分配的nodeID(猜测),解决方案是treeList1.SetFocusedNode(treeList1.FindNodeByKeyID(stateID));即利用findnode之类的函数去查询tree,找到新添加的结点,在将该节点作为SetFocusedNode的参数,则可以完成焦点的设置。
1.6 DevExpress.XtraTreeList查找结点函数FindNodeByKeyID()无效
tree的find这类函数,在进行查找时,需要注意参数的类型,例如,这个函数FindNodeByKeyID()是根据数据源里的主键进行结点查找,即你需要给定tree对应数据源中的记录的key,如果数据源中的key是整型,而我们利用一个字符串类型作为参数的话, FindNodeByKeyID(”100”)将不能找到节点,正确的写法应该是FindNodeByKeyID(100)。
1.7 DevExpress.XtraTreeList部分结点添加checkbox或者图片
有些时候,不想在所有节点前都添加checkbox或者想在结点前添加图片,此时需要手动添加事件CustomDrawNodeCheckBox的处理函数,在函数中为某些结点定制checkbox,或者图片,本处只着重说明定制checkbox,关于结点图片的代码可以参考网址https://www.devexpress.com/Support/Center/Question/Details/Q142494。上码,上图,如下:
private void treeList2_CustomDrawNodeCheckBox(object sender, DevExpress.XtraTreeList.CustomDrawNodeCheckBoxEventArgs e)
{
String variID = e.Node.GetValue("variID").ToString();//e.Node为tree的结点
//满足该条件的结点,为其设置checkbox,其他结点没有checkbox
if (variID == "")
{
DevExpress.XtraTreeList.ViewInfo.IndentInfo ii = treeList2.ViewInfo.RowsInfo[e.Node].IndentInfo;
int x2 = e.Bounds.Left + ii.LevelWidth / 2;
int y2 = e.Bounds.Top + e.Bounds.Height / 2;
int h2 = e.Bounds.Height / 2 + 1;
Rectangle r1 = new Rectangle(e.Bounds.Left, y2, e.Bounds.Width, 1);
Rectangle r2 = new Rectangle(x2, y2, 1, h2);
e.Graphics.FillRectangle(treeList2.ViewInfo.RC.TreeLineBrush, r1);
if (e.Node.Expanded)
{
e.Graphics.FillRectangle(treeList2.ViewInfo.RC.TreeLineBrush, r2);
}
e.Handled = true;
}
}


2. DevExpress.XtraGrid控件使用
该控件类是一个表格控件,但是其具有很多方便而使用的功能,例如可以对记录进行分组,可以再记录的前面加上checkbox,可以将具有相同值的cell进行合并等等。Grid分为两部分,DevExpress.XtraGrid.GridControl 和DevExpress.XtraGrid.Views.Grid.GridView,GridControl 主要负责数据源、控件整体尺寸等等方面的控制,GridView主要负责控件是否允许编辑、是否显示分组等信息,具体可以见VS属性窗口(本人也是限定在使用上,具体该控件为什么要分为两部分,每部分从设计的角度来讲起到什么作用等,还没有具体研究)。Grid的数据源的设置同tree类似,不在赘述,这里主要想介绍一下下面几个问题:
2.1 DevExpress.XtraGrid分组
设置好数据源后,只需要设置grid的groupIndex就可分组,操作:右键/run designer/colums/选择一个列/设置GroupIndex(当然设置前,你需要为grid添加一些column才可以)。分组需要以某一个列进行分组,该列必须要对应到数据源中的某个字段,即分组是按照数据源中的某些字段进行分组。grid可以显示多组,第一组的分组列的groupIndex为0,第二组的分组列的groupIndex为1,依此类推。下例中classID的groupIndex为0,stuNum的groupIndex为1。为了直观、易于理解,编了个小例子,上段代码和效果图,具体如下:
DataTable dt = new DataTable("table1");
dt.Columns.Add("classID", typeof(int));
dt.Columns.Add("className", typeof(String));
dt.Columns.Add("stuNum", typeof(int));
dt.Columns.Add("stuName", typeof(String));
dt.Columns.Add("courseName", typeof(String));
dt.Columns.Add("hours", typeof(String));
dt.Columns.Add("grade", typeof(String));

dt.Rows.Add(new object[] { 1, "计算机101班", 2014001, "李强", "数据库", "64", "90"});
dt.Rows.Add(new object[] { 1, "计算机101班", 2014001, "李强", "操作系统", "64", "100" });
dt.Rows.Add(new object[] { 1, "计算机101班", 2014001, "李强", "软件工程", "64", "80" });
dt.Rows.Add(new object[] { 1, "计算机101班", 2014002, "王伟", "数据库", "64", "90" });
dt.Rows.Add(new object[] { 1, "计算机101班", 2014002, "王伟", "数据库", "64", "90" });
dt.Rows.Add(new object[] { 1, "计算机101班", 2014002, "王伟", "数据库", "64", "90" });

dt.Rows.Add(new object[] { 2, "计算机102班", 2014003, "孙明", "数据库", "64", "90" });
dt.Rows.Add(new object[] { 2, "计算机102班", 2014003, "孙明", "操作系统", "64", "100" });
dt.Rows.Add(new object[] { 2, "计算机102班", 2014003, "孙明", "软件工程", "64", "80" });
dt.Rows.Add(new object[] { 2, "计算机102班", 2014004, "赵敏", "数据库", "64", "100" });
dt.Rows.Add(new object[] { 2, "计算机102班", 2014004, "赵敏", "数据库", "64", "90" });
dt.Rows.Add(new object[] { 2, "计算机102班", 2014004, "赵敏", "数据库", "64", "70" });



2.2 DevExpress.XtraGrid修改分组标题
如上图所示,分为两组,每组的标题为“列标题:值”,上例为“班级ID:1”,但有时需要根据记录中的值,动态修改分组标题。为gridView1添加CustomDrawGroupRow事件响应函数(注意是GridView而不是GridControl),在函数动态修改标题,为了不显示重复信息,可以将班级和学生姓名列隐藏。上码,上图,如下:
private void gridView1_CustomDrawGroupRow(object sender, DevExpress.XtraGrid.Views.Base.RowObjectCustomDrawEventArgs e)
{
DevExpress.XtraGrid.Views.Grid.ViewInfo.GridGroupRowInfo groRowInf = e.Info as
DevExpress.XtraGrid.Views.Grid.ViewInfo.GridGroupRowInfo;
int rowHan = groRowInf.RowHandle;
int rowLev = gridView1.GetRowLevel(rowHan);
if (rowLev == 0)
{
groRowInf.GroupText = "班级:" + gridView1.GetDataRow(rowHan)["className"].ToString();
}
if (rowLev == 1)
{
groRowInf.GroupText = gridView1.GetDataRow(rowHan)["stuName"].ToString();
}
}



...全文
78014 62 打赏 收藏 转发到动态 举报
写回复
用AI写文章
62 条回复
切换为时间正序
请发表友善的回复…
发表回复
下雨不打伞 2017-08-03
  • 打赏
  • 举报
回复
赞一个,好贴要赞,学习一下!
  • 打赏
  • 举报
回复
写的不错,如果能写到博客里更好
一转程序员 2017-04-10
  • 打赏
  • 举报
回复
很有参考价值,我刚开始用
savoyyang 2017-03-13
  • 打赏
  • 举报
回复
感谢楼主分享。
tanlanz 2017-03-13
  • 打赏
  • 举报
回复
兵工厂三剑客 2016-09-28
  • 打赏
  • 举报
回复
感谢楼主分享。
qq_27229087 2016-09-27
  • 打赏
  • 举报
回复
楼主很棒!所以想问问楼主和大家能否控制repositoryItemComboBox使其不显示滚动轴,而是自动显示所有下拉行。先谢谢大家了!
rebeva 2015-12-09
  • 打赏
  • 举报
回复
向楼主学习,敬礼!!
tianlangchua 2015-11-29
  • 打赏
  • 举报
回复
感谢楼主无私分享
Gavin608 2015-10-18
  • 打赏
  • 举报
回复
相当好的文章,我刚开始学,谢谢了
小鬼当家家 2015-09-18
  • 打赏
  • 举报
回复
以前也用过DEV,感觉确实不错。就是以前用的是盗版的DEV 13版本的,遇到一点问题,不知大家有没有遇到过,就是使用其中的RichEditControl控件的时候,在空间中输入英文‘-’是会导致程序崩溃,而且不能捕获异常。
tx686 2015-09-17
  • 打赏
  • 举报
回复
好东西,谢谢分享
  • 打赏
  • 举报
回复
太少了 , 才这么点点
tx686 2015-09-06
  • 打赏
  • 举报
回复
谢谢楼主分享
松林迷途 2015-07-14
  • 打赏
  • 举报
回复
这个必须要顶你一下了,我也在搞这个第三方控件编程。谢谢你的好帖啊。
tudiy 2015-06-22
  • 打赏
  • 举报
回复
赞一个!!!
gyl332915141 2015-06-22
  • 打赏
  • 举报
回复
感谢楼主分享,学到了很多东西。
john_QQ:2335298917 2015-06-14
  • 打赏
  • 举报
回复
感谢楼主分享
Q245418384 2015-06-13
  • 打赏
  • 举报
回复
guanerhouxue 2015-06-11
  • 打赏
  • 举报
回复
楼主辛苦了
加载更多回复(35)

111,042

社区成员

发帖
与我相关
我的任务
社区描述
.NET技术 C#
社区管理员
  • C#
  • AIGC Browser
  • by_封爱
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告

让您成为最强悍的C#开发者

试试用AI创作助手写篇文章吧