问题描述
虽然不是一名职业开发人员,但也开发过一些项目。每次项目工期都非常紧张,而且都或多或少地需要一些没有学习过的技术,大家都知道一涉及到新技术就会遇到很多问题,有时对于过来人来说一些不是问题的问题,在新手面前很可能是一个拦路虎,进而影响项目进度耽误工期,解决方案很简单,就是打开百度或者google查资料,看看别人是不是也遇到过类似的问题,怎么解决的,什么解决方案。干过这么多项目,真心说得益于互联网的便利,得益于大家的分享!如果没有网络,没有那么多技术大Boss在网上的热心解答,无私的技术支持与分享,不惜自己宝贵休息时间的奉献精神(这句主要是为了拔高,见谅:)),我想我们的开发速度不会这么快,项目的进度也不会那么顺利。所以,每次从网上找到答案并顺利解决问题时,兴奋高兴之余,更是心怀感激,而且还会假设如果没有Boss们的技术贴,该怎么办呢,项目干不完就又不能睡觉了!每每此时,我都想着等这个项目结束了,一定要将项目中遇到的一些难点和一些开发经验发到网上和大家分享,可是项目一结束,就忙这忙那,一会这事一会那事,根本没有时间发帖,时间一长,项目中的技术、难点、经验也都忘的差不多了,也没有当时那种得到馈赠,想及时予以回报的心情了,最后也就不写了(有没有和我一样的技术男,请对号入座),其实这些都是借口,是一种自私的表现,自己用完了,怕耽误自己的时间,也就不管别人了,如果你想做,就一定能找到时间,所以我说这是一种自私的表现(个人意见,如有不同看法,但还请保持冷静)。俗话说拿人手短,吃人嘴短!虽然之前一直没有到网上分享自己的经验,但内心也始终怀有一种自责之情。直到完成最近一个项目后,让我这种“短之情”达到了一种历史极值,迫使自己必须抽出时间分享一下不知是否能对后来人有所帮助的经历。这个项目是2014年10月底接手的,领导让我用C#进行开发,之前关于C#的经验较少,工期非常紧张,将近3个月(还有其他的工作要做,项目是一部分)。接到项目后,我做了一个DEMO,领导不太满意,界面不太美观,弹出窗体较多,不简洁,而且领导想要的“树表”(tree和grid控件的结合体)界面也没有实现(当时,是通过其他界面解决树表控件问题,但是界面不友好)。在我国,领导不满意,是一件非常大的事,千万不能掉以轻心,必须得引起重视。于是,日以继夜地找资料、找源码、找控件,最后找到两款控件一个是ComponentOne,另一个则是DevExpress,最后选择了DevExpress,个人认为后者的功能要强于前者(个人意见)。在DevExpress的支持下,我又重新做了Demo,showmyboss,结果领导比较满意,于是快速地进入项目的业务实现阶段,这一过程更得益于网络分享,快速掌握该控件的使用方法,以及解决DevExpress使用过程中遇到的各种问题,进而非常顺利地完成了项目的开发。真心地感谢,分享这些技术的每一个人。所以,在这个项目结束的三个多月后,我重新打开开发环境,利用将近两天的时间,一点一点一步一步总结、整理关于这个控件的使用方法和经验。所以,不求精、不求顶、不求名,只求本人的一点愚见能为您的项目开发或者DevExpress学习带来一丝微薄之力,足以。已经说了不少废话,言归正传。DevExpress和ComponentOne相比的话,我觉得DevExpress功能更加强大,有人说DevExpress速度慢,但用过之后发现,其带来的效率问题与程序本身的效率相比,可以忽略不计,所以DevExpress的效率不是问题。DevExpress是DeveloperExpress的缩写,DevExpress是一家全球知名的控件开发公司,生产很多产品,其中DXperience是一套关于.NET的用户界面控件套装(Winforms和Webforms),目前最全的版本的是DXperienceUniversalSubscription,简称DEV宇宙版。这个控件国内有代理,打算过段时间买一套最新的,也可以从老外那里买,差价估计在1-2W之间。本次项目开发采用的是DevExpress13.2.8,记不清是从官网上下的试用版,还是从网上随便找的,刚开始用的试用版,后来弄到了正版,但是可以破解,这个站上面就有破解程序,很容易的,而且没有必要弄更高的版本(高版本的貌似破解起来有难度,个人猜测),这个版本就可以完全满足winform类型的项目开发。本次需要分享的东西主要涉及两个控件的使用,一个树DevExpress.XtraTreeList,一个表格DevExpress.XtraGrid,这是两个功能非常强大的控件。1.DevExpress.XtraTreeList控件将其简称为tree,tree其实就是一个树表控件,他像树一样包含具有父子关系的若干节点,同时每个节点又是一个带有多个字段的记录。其用法非常简单方便,只需要为其配置带有父子关系的数据源,其就可以按照树的形式进行显示。1.1DevExpress.XtraTreeList配置数据源数据源一般是一个二维表,可以是数据库中的表,该表中要包含表示父子关系的两个字段,即主键和父亲的主键。下面的代码是手动创建的数据源DataTable。DataTabledtAllPath=newDataTable("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(newobject[]{1,0,"1","1",""});dtAllPath.Rows.Add(newobject[]{2,0,"2","2",""});dtAllPath.Rows.Add(newobject[]{3,1,"1.1","1.1",""});dtAllPath.Rows.Add(newobject[]{4,2,"2.1","2.1",""});treeList1.DataSource=dtAllPath;
上面的代码中,nodeID是每行记录的主键,parNodeID是每行记录的父亲记录的主键,0表示树的根结点。最后一行代码是将生成的数据源交给tree显示。当然为了完成树的显示工作,还需要配置tree的KeyFieldName属性为nodeID,ParentFieldName属性为parNodeID(选中tree,在vs的属性窗口设置),还需要为tree添加列并配置该列与数据源中的字段对应关系,右键tree控件选择rundesigner弹出下图,FieldName用来配置对应关系,tree中添加了两列,第一列和stateCode对应,designer可以配置tree的各种属性,列标题,cell中的字体颜色等等,不再一一赘述。1.2DevExpress.XtraTreeList添加checkbox在tree的结点中添加checkbox是一项非常实用常见的功能,设置起来非常简单,选中tree,在VS的属性窗口中,找到OptionsViewShowCheckBoxes,将其设置为true,即可。1.3DevExpress.XtraTreeList列表中添加ComboBox在tree控件中直接对信息进行编辑,有时可能需要用到ComboBox控件,具体添加方法,右键/rundesigner/选择列/ColumnEdit/New,为该列创建一个内嵌的ComboBox控件,即repositoryItemComboBox,具体如下图所示。1.4repositoryItemComboBox下拉表不能显示通过repositoryItemComboBox的click事件,向其动态add下拉列表中的items后,点击repositoryItemComboBox的下拉按钮,下拉列表闪一下就消失了(不是在click事件中添加items的情况,不会出现此问题)。解决方案,在repositoryItemComboBox的ButtonClick事件中,将事件源sender转换为ComboBoxEdit,再利用add函数添加item,最后手动显示下拉列表,代码如下:ComboBoxEditcombo=senderasComboBoxEdit;combo.Properties.Items.Add(…);combo.ShowPopup();1.5DevExpress.XtraTreeList设置焦点函数setFocusedNode()无效当使用TreeListNodeaddedNode=treeList1.AppendNode(参数略),向tree中添加一个节点后,一般想立刻使这个新添加的节点获得焦点,但此时如果直接使用treeList1.SetFocusedNode(addedNode)则无效,可能是因为addedNode中不包含tree为其分配的nodeID(猜测),解决方案是treeList1.SetFocusedNode(treeList1.FindNodeByKeyID(stateID));即利用findnode之类的函数去查询tree,找到新添加的结点,在将该节点作为SetFocusedNode的参数,则可以完成焦点的设置。1.6DevExpress.XtraTreeList查找结点函数FindNodeByKeyID()无效tree的find这类函数,在进行查找时,需要注意参数的类型,例如,这个函数FindNodeByKeyID()是根据数据源里的主键进行结点查找,即你需要给定tree对应数据源中的记录的key,如果数据源中的key是整型,而我们利用一个字符串类型作为参数的话,FindNodeByKeyID(”100”)将不能找到节点,正确的写法应该是FindNodeByKeyID(100)。1.7DevExpress.XtraTreeList部分结点添加checkbox或者图片有些时候,不想在所有节点前都添加checkbox或者想在结点前添加图片,此时需要手动添加事件CustomDrawNodeCheckBox的处理函数,在函数中为某些结点定制checkbox,或者图片,本处只着重说明定制checkbox,关于结点图片的代码可以参考网址https://www.devexpress.com/Support/Center/Question/Details/Q142494。上码,上图,如下:privatevoidtreeList2_CustomDrawNodeCheckBox(objectsender,DevExpress.XtraTreeList.CustomDrawNodeCheckBoxEventArgse){StringvariID=e.Node.GetValue("variID").ToString();//e.Node为tree的结点//满足该条件的结点,为其设置checkbox,其他结点没有checkboxif(variID==""){DevExpress.XtraTreeList.ViewInfo.IndentInfoii=treeList2.ViewInfo.RowsInfo[e.Node].IndentInfo;intx2=e.Bounds.Left+ii.LevelWidth/2;inty2=e.Bounds.Top+e.Bounds.Height/2;inth2=e.Bounds.Height/2+1;Rectangler1=newRectangle(e.Bounds.Left,y2,e.Bounds.Width,1);Rectangler2=newRectangle(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.1DevExpress.XtraGrid分组设置好数据源后,只需要设置grid的groupIndex就可分组,操作:右键/rundesigner/colums/选择一个列/设置GroupIndex(当然设置前,你需要为grid添加一些column才可以)。分组需要以某一个列进行分组,该列必须要对应到数据源中的某个字段,即分组是按照数据源中的某些字段进行分组。grid可以显示多组,第一组的分组列的groupIndex为0,第二组的分组列的groupIndex为1,依此类推。下例中classID的groupIndex为0,stuNum的groupIndex为1。为了直观、易于理解,编了个小例子,上段代码和效果图,具体如下:DataTabledt=newDataTable("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(newobject[]{1,"计算机101班",2014001,"李强","数据库","64","90"});dt.Rows.Add(newobject[]{1,"计算机101班",2014001,"李强","操作系统","64","100"});dt.Rows.Add(newobject[]{1,"计算机101班",2014001,"李强","软件工程","64","80"});dt.Rows.Add(newobject[]{1,"计算机101班",2014002,"王伟","数据库","64","90"});dt.Rows.Add(newobject[]{1,"计算机101班",2014002,"王伟","数据库","64","90"});dt.Rows.Add(newobject[]{1,"计算机101班",2014002,"王伟","数据库","64","90"});dt.Rows.Add(newobject[]{2,"计算机102班",2014003,"孙明","数据库","64","90"});dt.Rows.Add(newobject[]{2,"计算机102班",2014003,"孙明","操作系统","64","100"});dt.Rows.Add(newobject[]{2,"计算机102班",2014003,"孙明","软件工程","64","80"});dt.Rows.Add(newobject[]{2,"计算机102班",2014004,"赵敏","数据库","64","100"});dt.Rows.Add(newobject[]{2,"计算机102班",2014004,"赵敏","数据库","64","90"});dt.Rows.Add(newobject[]{2,"计算机102班",2014004,"赵敏","数据库","64","70"});
2.2DevExpress.XtraGrid修改分组标题如上图所示,分为两组,每组的标题为“列标题:值”,上例为“班级ID:1”,但有时需要根据记录中的值,动态修改分组标题。为gridView1添加CustomDrawGroupRow事件响应函数(注意是GridView而不是GridControl),在函数动态修改标题,为了不显示重复信息,可以将班级和学生姓名列隐藏。上码,上图,如下:privatevoidgridView1_CustomDrawGroupRow(objectsender,DevExpress.XtraGrid.Views.Base.RowObjectCustomDrawEventArgse){DevExpress.XtraGrid.Views.Grid.ViewInfo.GridGroupRowInfogroRowInf=e.InfoasDevExpress.XtraGrid.Views.Grid.ViewInfo.GridGroupRowInfo;introwHan=groRowInf.RowHandle;introwLev=gridView1.GetRowLevel(rowHan);if(rowLev==0){groRowInf.GroupText="班级:"+gridView1.GetDataRow(rowHan)["className"].ToString();}if(rowLev==1){groRowInf.GroupText=gridView1.GetDataRow(rowHan)["stuName"].ToString();}}
解决方案
本帖最后由 ninihaohao1234 于 2015-06-02 22:08:53 编辑
解决方案二:
2.3DevExpress.XtraGrid添加行号为了添加行号,需要添加GridView事件CustomDrawRowIndicator的处理函数,函数中每组所在行的索引从-1开始减小,普通记录行从0开始增加。注意需要在grid所在的窗体的加载事件(或者其他的form事件)处理函数中,加上一个代码gridView1.IndicatorWidth=50;,否则行号不能显示,原因没去研究。注意,当记录较多grid出现滚动条时,下述代码会导致行号错乱,需要注意,这里只是给出显示行号所需要的一些基本知识和原理。上码,上图,如下:privatevoidForm1_Load(objectsender,EventArgse){gridView1.IndicatorWidth=50;}privatevoidgridView1_CustomDrawRowIndicator(objectsender,DevExpress.XtraGrid.Views.Grid.RowIndicatorCustomDrawEventArgse){if(e.Info.IsRowIndicator){if(gridView1.GetRowLevel(e.RowHandle)<2){e.Info.DisplayText=(-e.RowHandle).ToString();}}gridView1.UpdateColumnsCustomization();}
3.关于DevExpress的一些资料上面大致的介绍了,tree和grid的使用方法,其实不是很难,只是对于新手而言,可以作为一个简单的参考,下面再介绍一下当时找到的一些技术贴,供大家参考。3.1给TreeList的根和子节点弹出不同的右键菜单http://blog.locoy.com/read-8.html3.2DevExpress窗体统一换肤http://blog.csdn.net/educast/article/details/47306313.3DevExpress在线帮助文档https://documentation.devexpress.com/#WindowsForms/DevExpressXtraBarsWinRTLiveTilesWinRTLiveTileManagerMembersTopicAll4.总结写将近小两天的时间,总结了一些东西,希望对于新手上路有些帮助,文中如有误导还请各位大神及时批评指正。其实项目中还有一些关于DevExpress使用方法的一些难点和问题,但由于项目结题已有三个月的时间,实在是记不得当时是哪里出现的问题,以及如何解决的,下次争取遇到就记录下来。最后还是要感谢那些分享自己技术经历的各位大师,感谢能够热心解答新手问题的各位好友,感谢大家的分享,让我们借助网络,我为人人,人人为我,能让我们在一个又一个的项目赶工中时刻感受到大家的力量、同行的支持,共同前行。奋斗小丁哥2015.06.02
解决方案三:
写的挺好的,一定能加精的。
解决方案四:
补充,在2.1节的代码中,漏了一句话,即将dt赋值给gridControl的数据源。
解决方案五:
谢谢,2楼,苏小喵,第一次发帖,谢谢支持!不知道怎么,直接给你回复,只能给自己回复了!
解决方案六:
这个要支持,如果能提供html或者doc版本就更好了
解决方案七:
解决方案八:
最近一直都在用DevExpress来做VIEW。确实有点慢,但也确实很漂亮,功能也很强大。
解决方案九:
谢谢楼主分享!
解决方案十:
该回复于2016-01-31 23:20:06被版主删除
解决方案十一:
DevExpress做出来的东西的确好看
解决方案十二:
该回复于2015-12-31 23:42:23被版主删除
解决方案十三:
不错,这个一定要授精!~~
解决方案十四:
不错不错。至于控件的用法,我一般都是去官网看example
解决方案十五:
来到这里就是分享的世界!
解决方案:
好东西,留言学习
解决方案:
DevExpress控件经常使用,你这个算是一个不错的实例了,感谢分享
解决方案:
dev用熟了还是很好用的
解决方案:
Dev用起来确实很方便,我现在也是一直用这个,只是速度上还是有些缺陷
解决方案:
真是感同身受,总是在网络上直接用别人的分享,心想:嗯,我也要把遇到的问题解决方法分享出来;最后却总是不了了之啊,我要向你学习!!
解决方案:
引用19楼Imcx_的回复:
真是感同身受,总是在网络上直接用别人的分享,心想:嗯,我也要把遇到的问题解决方法分享出来;最后却总是不了了之啊,我要向你学习!!
哈哈,我也是最近时间充裕了,发点东西,还还欠账
解决方案:
解决方案:
感谢楼主,赞个!!!
解决方案:
我查过慢的原因。慢在正版验证那个算法上,那个算法有时候会阻塞当前线程好几秒钟。只要起动的时候,用一个线程去加载一个包含你所有使用控件的窗口。速度就会快很多。仅对winform有效。
解决方案:
解决方案:
解决方案:
解决方案:
感谢楼主分享
解决方案:
真心不错。赞一个,支持啊,顶啊,赞啊。
解决方案:
解决方案:
好高深,看不懂。
解决方案:
刚做完的项目就用的dev,感觉这玩意有的地方很强大有的地方弱的不行,你觉得它应该提供的功能结果它没有,官方会告诉你用几个控件加几个事件结合...真TM蛋疼...
解决方案:
谢谢你!!!!!!!!!!!!!学习了!!!!!!!!!!!!!!!!!!!!!!!!!!
解决方案:
谢谢楼主,我是即将毕业的学生,学到了点
解决方案:
总结的很好,初接触DevExpress的程序员上手比较难,值得一看
解决方案:
我经历过从8升到11,马上可能要用13了,谢谢分享~
解决方案:
有没有用过DotNetBar的?这个和dev比哪个好用呢?
解决方案:
谢谢分享放到博客里,让更多人看到把
解决方案:
学习到了,好安逸,巴适惨了!!!
解决方案:
该回复于2016-02-28 23:37:10被版主删除
解决方案:
这些代码挺不错的。
解决方案:
第三方控件真的漂亮
解决方案:
楼主辛苦了
解决方案:
解决方案:
解决方案:
感谢楼主分享
解决方案:
感谢楼主分享,学到了很多东西。
解决方案:
赞一个!!!
解决方案:
这个必须要顶你一下了,我也在搞这个第三方控件编程。谢谢你的好帖啊。
解决方案:
谢谢楼主分享
解决方案:
太少了,才这么点点