基于WPF技术的甘特图控件的研究与设计

发布时间:2023-04-27 22:32:34   来源:文档文库   
字号:
基于WPF技术的甘特图控件的研究与设计
邹海;余籦超
【摘要】TraditionalWindowsFormapplicationshavehighcomplexdegreeandpoorperformanceinrenderinggraphics,butGanttchartcontroloftenneedstodrawalotofgraphics.Inviewofthissituation,weusethenovelgraphicsrenderingtechnology---WPF(WindowsPresentationFoundationofMicrosoft,withthestructureddesignnotionweapplyaseriesofthenewfeaturessuchasnoappearancecontrol,stylesheets,triggerandsoonprovidedbyWPFtocreateGanttchartcontrol,whichiseasierinrealisationprocessandmoreexcellentinper-formanceandappearance.%传统的Windows窗体应用程序在图形渲染方面复杂程度高,运行性能差,而甘特图控件往往需要绘制大量的图形。针对这种情况,运用微软全新的图形渲染技术---WPFWindowsPresentationFoundation),以结构化的设计思想,使用WPF提供的无外观控件、样式表、触发器等一系列新特性来创建甘特图控件。实现过程更加简易,性能与外观上表现也更加出色。【期刊名称】《计算机应用与软件》【年(,期】2014(000005【总页数】4(P50-52,78【关键词】WPF;控件;甘特图【作者】邹海;余籦超

【作者单位】安徽大学计算机科学与技术学院安徽合肥230601;安徽大学计算机科学与技术学院安徽合肥230601【正文语种】【中图分类】TP311.520引言
传统的Windows应用程序依靠User32库以及GDI/GDI+1]来对控件、图像以及文本进行渲染。WPFDirectX技术为基础,为2D3D图形提供了更好的渲染效果[23]。WPF通过统一的编辑模型,对2D3D、控件以及视频、语音等进行整合,特别是与XAML45]技术结合,运用XML的语法方式以声明式的编程方式,为软件的开发特别是UI(UserInterface部分的设计带来了极大的便利[6]。在图形渲染方面,WPF使用矢量图形,采用与分辨率无关的单位,使得应用程序在不同的DPI下都可以获得最佳的显示效果。此外,WPF硬件加速以及富创作等特性,使得可以在构建绚丽的UI的同时获得最佳的性能。甘特图是各类项目管理中广为采用的一种图件。本文以甘特图控件为例,详细阐述WPF术在控件设计与开发中的应用方法。1甘特图控件的设计与实现
甘特图主要组成部分:(1任务控件。每个任务控件都是甘特表中的一条数据项的图形化表示,并且可以对它进行相关操作,比如拉伸与移动;(2甘特图容器。在WPF中,每个控件必须放入一个容器中才能进行绘制。对于甘特图,每个任务控件都位于这样一个甘特图容器中,它提供一个布局算法来对其中所包含的每个任务控件进行布局;(3时间栏。它的作用就相当绘制函数时的坐标系,对于甘特图中每个任务,最基本的要素就是任务的开始时间与结束时间,而时间栏正相当于这样一个坐标系,

根据任务的开始时间与结束时间来决定该任务的在甘特图中的位置以及任务条的长;(4甘特表。用于显示每个任务的具体信息,如:编号、任务名称、开始时间、结束时间、工期、前置任务等。1.1数据模型
这里采用数据库来存储该控件所需的数据。本文的重点是用阐述使用WPF的新特性来设计甘特图,甘特图自身的相关知识在这里不详述,而且出于简单起见,只列出部分字段,如表1所示(数据库采用Access
1任务信息表用来区分不同的任务ID数字对应在甘特图左边数据表中的“编号”EventName文本任务的名称StartDate日期/时间任务的开始时间EndDate日期/时间任务的结束时间IsScope/该任务是不是一个摘要任务PercentageGuid文本全局统一标识,数字任务完成的百分比1.2任务控件的实现
这里将每个任务看成是一个控件,使用WPF的自定控件技术来构建无外观控件,而将外观的定义以及触发器等放在样式表中来实现,这样就实现了控件逻辑与控件外观的分离。使用WPF的依赖属性来定义每个任务所需要的属性。将每个任务看成一个控件的好处除了逻辑上的清晰外,还便于一些鼠标事件的实现,比如拖动、拉伸、悬停等。1依赖项属性
建立一个名为EventWPF自定义控件,在生成的文件中可以看到,类Event继承自UserControl的,所以自定义控件都继承该类。接下来就是定义该控件的依赖项属性[7]。这里以任务的开始时间来说明如何定义依赖项属性以及为什么要使用依赖项属性。
定义依赖项属性(注意修饰符以及关键字DependencyProperty:publicstaticreadonlyDependencyPropertyStartDateProperty;

(1注册依赖项属性必须在类的静态构造函数中定义,通过
DependencyProperty.Register方法来注册依赖项属性。这里用的一个技巧就是定义一个FramworkPropertyMetadata,并将它作为参数提供给
DependencyProperty.Register方法,在定义FramworkPropertyMetadata我们使用FrameworkPropertyMetadataOptions枚举来添加一些附加功能。这里使用枚举值AffectsArrangeAffectsMeasure,其作用是当此属性发生改变时会重新测量和布局该控件。这样当改变一个任务的开始时间时,它就会自动进行重绘,位置和长度会自动改变。
(2添加属性包装器依赖项属性的访问与设置需要使用GetValue方法与SetValue方法,为了像.net中的属性那样访问依赖项属性,下面使用属性包装器来包装它。同时使用依赖项属性便于数据绑定。
2数据上下文及数据绑定
在该类的普通构造函数中,设置该控件的样式表以及数据上下文,这里样式表是作为一个资源访问的:
这里构造参数是一个EventInfo类型,里面定义了和该类相同的属性,不过都是普通属性,将它作为任务控件的数据上下文的作用是便于在样式表中定义数据绑定2],然后再将该样式应用于此控件。3EventInfo
关于每个任务的相关数据(开始时间、结束时间、任务名称等等保存在数据库中,在程序加载时将数据表中读取为ListEventInfo>,将其绑定到甘特表上,对于List中的每一个EventInfo实例,将其作为一个任务控件的数据上下文,并在控件Style里进行双向数据绑定,这样在对控件进行操作,比如移动和拉伸时,会修

改控件的相关依赖项属性。由于进行了数据绑定,控件对应的EventInfo实例的数据也会进行相应修改,同时EventInfo又与甘特表进行了数据绑定,这样数据表部分也会同时进行更新,保存数据时可以将ListEventInfo>写回数据库,整个数据组织结构如图1所示。1数据结构图
由于EventInfo是自定义的普通类,要实现它与控件的依赖项属性的双向绑定,所以必须对EventInfo类实现INotifyPropertyChanged接口,从而使得EventInfo类的属性发生改变时通知绑定,从而进行更新。4拉伸与移动
一个任务控件最基本的鼠标操作就是拉伸与移动,通过在任务控件两端进行拉伸来改变一个任务的开始时间或结束时间,通过移动一个任务可保持任务的工期不变,开始时间与结束时间同时改变。在此通过两个类来实现这个功能:MoveThumbRemoveThumb。这两个类都是继承自Thumb类。这里使用该类的目的是为了实现鼠标的拖放事件,可以分别定义Drag-StartedDragDelta
DragCompleted三个事件来分别响应拖放开始、拖放中以及拖放结束时要执行的操作。在拖放开始时,可以通过数据上下文来获得该控件(数据上下文是在样式表中的数据模板中实现的,然后在拖放事件时对该控件的开始时间及结束时间进行修改并且控件会自动重绘,这样就实现了动态效果,在拖放结束时也可以进行一些操作,如验证等。5样式表
该控件的逻辑部分实现后,接下来就要定义控件的外观。可以通过编写一个样式表,定义设置器、数据绑定、控件模板以及相关的触发器[7],然后将该样式表应用于控件。关于设置器与数据绑定的部分如前所述,下面主要讨论控件模板,通过定义控件模板就可以方便地定义一个控件的外观,这里定义的控件模板主要包含一个

GridGrid中主要包含三个矩形,如图2所示。2甘特任务结构示意图
这里以三种线型标识三个矩形,双线矩形跨三行,它是控件的大轮廓,单线矩形表示了百分比槽,虚线矩形表示了百分比的值。在定义每个矩形时还涉及到一些数据绑定,这样矩形的长度就绑定到相应控件的数据上了。这里可以把之前实现的MoveThumbRemoveThumb放入模板中,并定义为透明的,需要两个
RemoveThumb,分别位于控件的两端,一个MoveThumb位于控件的中间区域。下面在Style中设置控件的外观并进行相关的数据绑定。其语法简单,在Style的设置器中实现,如下:
<SetterProperty=″StartDate″Value=″{BindingPath=StartDate,Mode=TwoWay}″/>
第一个StartDate是指该控件的依赖项属性,第二个Start-Date是该控件的数据上下文中EventInfo实例的普通属性,ModeTwoWay即定义的绑定的模式为双向绑定。
还可以定义触发器,这里我们定义一个属性触发器,根据控件的IsScope属性,该属性决定了任务是一个普通任务还是一个摘要任务。这个属性触发器可以在IsScope为真时定义另一个数据模板,这样控件的外观就会随着IsScope属性值而发生变化。2甘特图容器的实现
WPF中的所有容器都是继承自Panel类,但鉴于该容器要对其所包含的每个任务控件的位置精确布局,所以这里采用的甘特图控件继承自Canvas,接下来要做的就是重写两个方法:MeasureOverrideArrangeOverride,前者的作用是计算每个任务控件的大小,后者的作用是确定每个控件在容器中的具体位置。重写这两个方法后,当任务控件放入甘特图容器后,就会自动计算其大小并精确布局。

3背景与时间表
背景与时间表都是通过WPF2D引擎来绘制的,这里单独定义了一个继承自Canvas的容器,然后定义一个绘制背景和时间表的方法,最后定义一些事件,当事件触发时执行这个绘制函数。这里要用到Visual对象,然后通过它的RenderOpeny方法来获得一个DrawingContext对象,接着调用
DrawingContext对象的相关方法进行图形绘制。当绘制完成时,将该Visual象放入一个VisualCollection中,这里需要重写两个函数,Visual-ChildrenCount方法和GetVisualChild方法,前者返回VisualCollection中所包含的Visual对象的个数,后者返回VisualCollection中对应的Visual对象。这样WPF就会将VisualCollection中的每个Visual对象绘制出来。4甘特表
甘特表的部分可以直接使用DataGrid类,然后通过样式表定义数据模板以及一些触发器,关键的数据部分可以用数据绑定来实现,具体通过将它的ItemsSource赋一个列表对象(ObservableCollection列表5应用实例
基于上述WPF技术,系统地研制了一个外表美观、功能完善的甘特图控件,并成功应用于国内某煤矿矿井建设工程施工的项目管理,下面结合该实例来说明设计流程与核心算法。5.1流程图
甘特图的呈现流程如图3所示,其中Max值为当前屏幕可视区域的垂直高度,VerOffset值在初次载入时的值为0,这样会从第一条数据开始显示,当甘特图载入之后,通过调整滚动条,会改变VerOffset的值,从而决定显示的第一条数据对应为数据库中的第几条数据,这样便呈现出了页面的滚动效果。这样的设计可以使WPF绘图引擎只绘制可视范围内的任务条,从而优化了甘特图呈现的速度及页

面滚动时的响应度。3甘特图生成流程图5.2核心算法列举
当任务加入自定义的容器后,容器会根据算法1与算法2来进行测量与排版,最终呈现完整的甘特图。
算法1重写MeasuerOverride函数
①容器中的Children数等于0,返回Size(00,结束。
②容器中的Children数大于0,初始化WidthHeight的值为0,遍历容器的Children中的对象,调用其Measure方法。
③更新Width值与Height值,其中Height值每次的增量为任务条的高度加上任务条之间的空隙,Width取当前值与当前任务条右端值中较大的值。④遍历结束,返回Size(WidthHeight。此为整个甘特图的大小。算法2重写ArrangeOverride函数
①初始化OriginPoint=newPoint(00,此为起始点坐标,初始化x=0y=0此为当前待排版任务条的坐标。
②遍历Children中的对象,获取对象的宽高值widthheight
③根据任务的开始时间、序号以及widthheight值来更新xy的当前值,从而确定任务条左上角的坐标点childPoint=newPoint(xy
④调用系统函数Canvas.SetTop(Canvas.SetLeft(来设置当前对象的坐标。⑤调用对象的Arrange(方法来对当前对象的位置进行排版。5.3效果截图
软件运行时的效果如图4所示。4某煤矿建井工程施工计划排队图6结语

本文以甘特图控件的设计与实现为例,详细讨论了WPF的一些新特性,比如依赖项属性、自定义控件、自定义容器、样式表、触发器以及XAML这种声明式编程方式。通过上文的描述可以发现,利用WPF技术的这些新特性在实现甘特图比传统方式要便利得多,很多细节可完全交由WPF来实现,无论是在开发的复杂程度以及运行的性能优化方面都有很大的提升,并且在外观上有了更大的发挥空间,不像传统的WinForm应用程序,控件的外观无法自定义,这让你构建华丽的UI为可能。参考文献
1EricWhite.GDI+程序设计[M.清华大学出版社,2002.
2CharlesPetzold.Application=Code+Markup:AGuidetotheMicrosoftWindowsPresentationFoundationM.MicrosoftPress2006.
3]王德才,崔欣.Windows图形开发技术分析[C//全国第19届计算机技术与应用(CACIS学术会议,2008.
4GlobaLSYermolchevFV.ToolofsystemprototypevisualizationC//MicrowaveTelecommunicationTechnology2008.
5LoriAMacVittie.XAMLinaNutshellM].O’Reilly,2006.6AdamNathan.WindowsPresntationFoundationUnleashedM.Sams2006.
7MatthewMacDonald.ProWPFinC#2010M.Apress2010.8]琚彬.基于WPF平台的自定义控件开发[D.西安电子科技大学,2008.


本文来源:https://www.2haoxitong.net/k/doc/03e5e270ab956bec0975f46527d3240c8447a11e.html

《基于WPF技术的甘特图控件的研究与设计.doc》
将本文的Word文档下载到电脑,方便收藏和打印
推荐度:
点击下载文档

文档为doc格式