WindowsForm如何实现类似微软project软件的甘特图?

  在管理软件研发过程中,特别是涉及项目管理或者生产计划方面,都需要一款类似微软project的控件对项目下的分解任务进行图形展示(甘特图)。下面介绍一下在WindowsForm下如何实现类似微软project软件的甘特图?最终的效果如下所示:

1、VS2012创建一个Windows应用程序GanttChartControl,并添加甘特图控件库,结构如下:

(注:此处甘特图控件是一款开源库,源码可从网上自行下载)

2、自定义任务类和资源类,代码如下:

 1  #region 自定义任务和资源类
 2     /// <summary>
 3     ///自定义资源
 4     /// </summary>
 5     [Serializable]
 6     public class MyResource
 7     {
 8         public string Name { get; set; }
 9     }
10     /// <summary>
11     /// 自定义任务类,继承 Task 接口 (可选)
12     /// </summary>
13     [Serializable]
14     public class MyTask : Task
15     {
16         public MyTask(ProjectManager manager) : base()
17         {
18             Manager = manager;
19         }
20 
21         private ProjectManager Manager { get; set; }
22 
23         public new int Start { get { return base.Start; } set { Manager.SetStart(this, value); } }
24         public new int End { get { return base.End; } set { Manager.SetEnd(this, value); } }
25         public new int Duration { get { return base.Duration; } set { Manager.SetDuration(this, value); } }
26         public new float Complete { get { return base.Complete; } set { Manager.SetComplete(this, value); } }
27     }
28     #endregion 

为了能够保存甘特图信息,需要将任务类和资源类标志为[Serializable]。自定义任务类需要继承Task接口。
3、创建项目和任务,代码如下:

 1             // 创建项目和任务
 2             _mManager = new ProjectManager();
 3             var p项目= new MyTask(_mManager) { Name = "项目" };
 4             _mManager.Add(p项目);
 5             var t售前任务组 = new MyTask(_mManager) { Name = "售前阶段" };
 6             var t项目启动 = new MyTask(_mManager) { Name = "项目启动会" };
 7             var t需求调研 = new MyTask(_mManager) { Name = "需求调研" };
 8             var t方案撰写 = new MyTask(_mManager) { Name = "方案撰写" };
 9             var t方案确认 = new MyTask(_mManager) { Name = "方案确认" };
10             // 用ProjectManager类Add方法添加任务
11             _mManager.Add(t售前任务组);
12             _mManager.Add(t项目启动);
13             _mManager.Add(t需求调研);
14             _mManager.Add(t方案撰写);
15             _mManager.Add(t方案确认);

首先需要用 ProjectManager  _mManager = new ProjectManager();创建一个ProjectManager,后续所有的任务都需要添加到此类Add方法添加任务进行管理。

任务的其他属性用下述代码进行设置:

 1          // 用ProjectManager类SetDuration方法设置任务工期
 2             _mManager.SetDuration(t项目启动, 3);
 3             _mManager.SetDuration(t需求调研, 5);
 4             _mManager.SetDuration(t方案撰写, 7);
 5             _mManager.SetDuration(t方案确认, 4);
 6             _mManager.SetDuration(tUI设计, 3);
 7             _mManager.SetDuration(t数据库设计, 5);
 8 
 9             //用ProjectManager类Split方法对任务进行分段
10             _mManager.Split(t数据库设计, new MyTask(_mManager), new MyTask(_mManager), 2);
11 
12             // 设置任务的完成率
13             t项目启动.Complete = 0.9f;
14             t需求调研.Complete = 0.5f;
15             t方案撰写.Complete = 0.4f;

 

4、任务分组和任务衔接关系定义

有了任务后,可以对任务的上下关系(分组)和接替关系进行定义,代码如下:

 1 // 给任务分组
 2             _mManager.Group(p项目, t售前任务组);
 3             _mManager.Group(p项目, t开发阶段);
 4             _mManager.Group(p项目, t实施阶段);
 5         
 6 
 7             _mManager.Group(t售前任务组, t项目启动);
 8             _mManager.Group(t售前任务组, t需求调研);
 9             _mManager.Group(t售前任务组, t方案撰写);
10             _mManager.Group(t售前任务组, t方案确认);
11             //任务衔接关系设置,不支持类型
12             _mManager.Relate(t项目启动, t需求调研);
13             _mManager.Relate(t需求调研, t方案撰写);
14             _mManager.Relate(t方案撰写, t方案确认);
15 
16 
17             _mManager.Group(t开发阶段, tUI设计);
18             _mManager.Group(t开发阶段, t数据库设计);
19             _mManager.Group(t开发阶段, t编码);
20             _mManager.Group(t开发阶段, t测试);
21 
22             _mManager.Relate(t方案确认, tUI设计);
23 
24             _mManager.Relate(tUI设计, t数据库设计);
25             _mManager.Relate(t数据库设计, t编码);
26             _mManager.Relate(t编码, t测试);
27 
28             _mManager.Group(t实施阶段, t系统安装和初始化);
29             _mManager.Group(t实施阶段, t系统培训);
30             _mManager.Group(t实施阶段, t系统验收);
31             _mManager.Group(t实施阶段, t结项);
32 
33             _mManager.Relate(t测试, t系统安装和初始化);
34             _mManager.Relate(t系统安装和初始化, t系统培训);
35             _mManager.Relate(t系统培训, t系统验收);
36             _mManager.Relate(t系统验收, t结项);

5、资源分配

 1           // 创建并设置任务资源(人、材料、设备等),任务资源可自定义
 2             var jake = new MyResource() { Name = "Jake" };
 3             var peter = new MyResource() { Name = "Peter" };
 4             var john = new MyResource() { Name = "John" };
 5             var lucas = new MyResource() { Name = "Lucas" };
 6             var james = new MyResource() { Name = "James" };
 7             var mary = new MyResource() { Name = "Mary" };
 8             // 给任务分配资源
 9             _mManager.Assign(t项目启动, jake);
10             _mManager.Assign(t项目启动, peter);
11             _mManager.Assign(t项目启动, john);
12             _mManager.Assign(t需求调研, jake);
13             _mManager.Assign(t需求调研, james);
14             _mManager.Assign(t数据库设计, james);
15             _mManager.Assign(t数据库设计, lucas);
16             _mManager.Assign(t方案撰写, mary);
17             _mManager.Assign(t方案撰写, lucas);
18             _mManager.Assign(t方案撰写, john);

6、甘特图初始化

 1             //甘特图初始化并创建任务代理
 2             _mChart.Init(_mManager);
 3             _mChart.CreateTaskDelegate = delegate() { return new MyTask(_mManager); };
 4 
 5             // 任务事件监听
 6             _mChart.TaskMouseOver += new EventHandler<TaskMouseEventArgs>(_mChart_TaskMouseOver);
 7             _mChart.TaskMouseOut += new EventHandler<TaskMouseEventArgs>(_mChart_TaskMouseOut);
 8             _mChart.TaskSelected += new EventHandler<TaskMouseEventArgs>(_mChart_TaskSelected);
 9             _mChart.PaintOverlay += _mOverlay.ChartOverlayPainter;
10             //允许任务拖拽
11             _mChart.AllowTaskDragDrop = true;
12 
13             // 设置任务提示内容,可自定义
14             _mChart.SetToolTip(t项目启动, string.Join(", ", _mManager.ResourcesOf(t项目启动).Select(x => (x as MyResource).Name)));
15             _mChart.SetToolTip(t需求调研, string.Join(", ", _mManager.ResourcesOf(t需求调研).Select(x => (x as MyResource).Name)));
16             _mChart.SetToolTip(t数据库设计, string.Join(", ", _mManager.ResourcesOf(t数据库设计).Select(x => (x as MyResource).Name)));
17             _mChart.SetToolTip(t方案撰写, string.Join(", ", _mManager.ResourcesOf(t方案撰写).Select(x => (x as MyResource).Name)));
18 
19             //设置图形日期信息
20             _mManager.TimeScale = TimeScale.Day;
21             var span = DateTime.Today - _mManager.Start;
22             _mManager.Now = (int)Math.Round(span.TotalDays);
23             // 设置图形标题显示日期格式
24             _mChart.TimeScaleDisplay = TimeScaleDisplay.DayOfWeek; 

7、完成后的界面为:

后台完整代码为:

  1 using System;
  2 using System.Collections.Generic;
  3 using System.ComponentModel;
  4 using System.Data;
  5 using System.Drawing;
  6 using System.Linq;
  7 using System.Text;
  8 using System.Windows.Forms;
  9 using Braincase.GanttChart;
 10 namespace GanttChartControl
 11 {
 12     /// <summary>
 13     /// 甘特图控件使用演示
 14     /// </summary>
 15     public partial class ExampleFull : Form
 16     {
 17         OverlayPainter _mOverlay = new OverlayPainter();
 18 
 19         ProjectManager _mManager = null;
 20 
 21         /// <summary>
 22         /// Example starts here
 23         /// </summary>
 24         public ExampleFull()
 25         {
 26             InitializeComponent();
 27 
 28             // 创建项目和任务
 29             _mManager = new ProjectManager();
 30             var p项目= new MyTask(_mManager) { Name = "项目" };
 31             _mManager.Add(p项目);
 32             var t售前任务组 = new MyTask(_mManager) { Name = "售前阶段" };
 33             var t项目启动 = new MyTask(_mManager) { Name = "项目启动会" };
 34             var t需求调研 = new MyTask(_mManager) { Name = "需求调研" };
 35             var t方案撰写 = new MyTask(_mManager) { Name = "方案撰写" };
 36             var t方案确认 = new MyTask(_mManager) { Name = "方案确认" };
 37             // 用ProjectManager类Add方法添加任务
 38             _mManager.Add(t售前任务组);
 39             _mManager.Add(t项目启动);
 40             _mManager.Add(t需求调研);
 41             _mManager.Add(t方案撰写);
 42             _mManager.Add(t方案确认);
 43             var t开发阶段 = new MyTask(_mManager) { Name = "开发阶段" };
 44             var tUI设计 = new MyTask(_mManager) { Name = "UI设计" };
 45             var t数据库设计 = new MyTask(_mManager) { Name = "数据库设计" };
 46             var t编码 = new MyTask(_mManager) { Name = "编码" };
 47             var t测试 = new MyTask(_mManager) { Name = "测试" };
 48             _mManager.Add(t开发阶段);
 49             _mManager.Add(tUI设计);
 50             _mManager.Add(t数据库设计);
 51             _mManager.Add(t编码);
 52             _mManager.Add(t测试);
 53             var t实施阶段 = new MyTask(_mManager) { Name = "实施阶段" };
 54             var t系统安装和初始化 = new MyTask(_mManager) { Name = "系统安装和初始化" };
 55             var t系统培训 = new MyTask(_mManager) { Name = "系统培训" };
 56             var t系统验收 = new MyTask(_mManager) { Name = "系统验收" };
 57             var t结项 = new MyTask(_mManager) { Name = "结项" };
 58             _mManager.Add(t实施阶段);
 59             _mManager.Add(t系统安装和初始化);
 60             _mManager.Add(t系统培训);
 61             _mManager.Add(t系统验收);
 62             _mManager.Add(t结项);
 63            
 64 
 65             // 用ProjectManager类SetDuration方法设置任务工期
 66             _mManager.SetDuration(t项目启动, 3);
 67             _mManager.SetDuration(t需求调研, 5);
 68             _mManager.SetDuration(t方案撰写, 7);
 69             _mManager.SetDuration(t方案确认, 4);
 70             _mManager.SetDuration(tUI设计, 3);
 71             _mManager.SetDuration(t数据库设计, 5);
 72 
 73             //用ProjectManager类Split方法对任务进行分段
 74             _mManager.Split(t数据库设计, new MyTask(_mManager), new MyTask(_mManager), 2);
 75 
 76             // 设置任务的完成率
 77             t项目启动.Complete = 0.9f;
 78             t需求调研.Complete = 0.5f;
 79             t方案撰写.Complete = 0.4f;
 80 
 81             // 给任务分组
 82             _mManager.Group(p项目, t售前任务组);
 83             _mManager.Group(p项目, t开发阶段);
 84             _mManager.Group(p项目, t实施阶段);
 85         
 86 
 87             _mManager.Group(t售前任务组, t项目启动);
 88             _mManager.Group(t售前任务组, t需求调研);
 89             _mManager.Group(t售前任务组, t方案撰写);
 90             _mManager.Group(t售前任务组, t方案确认);
 91             //任务衔接关系设置,不支持类型
 92             _mManager.Relate(t项目启动, t需求调研);
 93             _mManager.Relate(t需求调研, t方案撰写);
 94             _mManager.Relate(t方案撰写, t方案确认);
 95 
 96 
 97             _mManager.Group(t开发阶段, tUI设计);
 98             _mManager.Group(t开发阶段, t数据库设计);
 99             _mManager.Group(t开发阶段, t编码);
100             _mManager.Group(t开发阶段, t测试);
101 
102             _mManager.Relate(t方案确认, tUI设计);
103 
104             _mManager.Relate(tUI设计, t数据库设计);
105             _mManager.Relate(t数据库设计, t编码);
106             _mManager.Relate(t编码, t测试);
107 
108             _mManager.Group(t实施阶段, t系统安装和初始化);
109             _mManager.Group(t实施阶段, t系统培训);
110             _mManager.Group(t实施阶段, t系统验收);
111             _mManager.Group(t实施阶段, t结项);
112 
113             _mManager.Relate(t测试, t系统安装和初始化);
114             _mManager.Relate(t系统安装和初始化, t系统培训);
115             _mManager.Relate(t系统培训, t系统验收);
116             _mManager.Relate(t系统验收, t结项);
117 
118        
119 
120             // 创建并设置任务资源(人、材料、设备等),任务资源可自定义
121             var jake = new MyResource() { Name = "Jake" };
122             var peter = new MyResource() { Name = "Peter" };
123             var john = new MyResource() { Name = "John" };
124             var lucas = new MyResource() { Name = "Lucas" };
125             var james = new MyResource() { Name = "James" };
126             var mary = new MyResource() { Name = "Mary" };
127             // 给任务分配资源
128             _mManager.Assign(t项目启动, jake);
129             _mManager.Assign(t项目启动, peter);
130             _mManager.Assign(t项目启动, john);
131             _mManager.Assign(t需求调研, jake);
132             _mManager.Assign(t需求调研, james);
133             _mManager.Assign(t数据库设计, james);
134             _mManager.Assign(t数据库设计, lucas);
135             _mManager.Assign(t方案撰写, mary);
136             _mManager.Assign(t方案撰写, lucas);
137             _mManager.Assign(t方案撰写, john);
138 
139             //甘特图初始化并创建任务代理
140             _mChart.Init(_mManager);
141             _mChart.CreateTaskDelegate = delegate() { return new MyTask(_mManager); };
142 
143             // 任务事件监听
144             _mChart.TaskMouseOver += new EventHandler<TaskMouseEventArgs>(_mChart_TaskMouseOver);
145             _mChart.TaskMouseOut += new EventHandler<TaskMouseEventArgs>(_mChart_TaskMouseOut);
146             _mChart.TaskSelected += new EventHandler<TaskMouseEventArgs>(_mChart_TaskSelected);
147             _mChart.PaintOverlay += _mOverlay.ChartOverlayPainter;
148             //允许任务拖拽
149             _mChart.AllowTaskDragDrop = true;
150 
151             // 设置任务提示内容,可自定义
152             _mChart.SetToolTip(t项目启动, string.Join(", ", _mManager.ResourcesOf(t项目启动).Select(x => (x as MyResource).Name)));
153             _mChart.SetToolTip(t需求调研, string.Join(", ", _mManager.ResourcesOf(t需求调研).Select(x => (x as MyResource).Name)));
154             _mChart.SetToolTip(t数据库设计, string.Join(", ", _mManager.ResourcesOf(t数据库设计).Select(x => (x as MyResource).Name)));
155             _mChart.SetToolTip(t方案撰写, string.Join(", ", _mManager.ResourcesOf(t方案撰写).Select(x => (x as MyResource).Name)));
156 
157             //设置图形日期信息
158             _mManager.TimeScale = TimeScale.Day;
159             var span = DateTime.Today - _mManager.Start;
160             _mManager.Now = (int)Math.Round(span.TotalDays);
161             // 设置图形标题显示日期格式
162             _mChart.TimeScaleDisplay = TimeScaleDisplay.DayOfWeek; 
163 
164             // UI初始化
165             _InitExampleUI();
166             //隐藏说明(打印模式隐藏)
167             _mOverlay.PrintMode = true;
168     
169            
170         }
171 
172         void _mChart_TaskSelected(object sender, TaskMouseEventArgs e)
173         {
174             _mTaskGrid.SelectedObjects = _mChart.SelectedTasks.Select(x => _mManager.IsPart(x) ? _mManager.SplitTaskOf(x) : x).ToArray();
175             _mResourceGrid.Items.Clear();
176             _mResourceGrid.Items.AddRange(_mManager.ResourcesOf(e.Task).Select(x => new ListViewItem(((MyResource)x).Name)).ToArray());
177         }
178 
179         void _mChart_TaskMouseOut(object sender, TaskMouseEventArgs e)
180         {
181             lblStatus.Text = "";
182             _mChart.Invalidate();
183         }
184 
185         void _mChart_TaskMouseOver(object sender, TaskMouseEventArgs e)
186         {
187             lblStatus.Text = string.Format("{0} to {1}", _mManager.GetDateTime(e.Task.Start).ToLongDateString(), _mManager.GetDateTime(e.Task.End).ToLongDateString());
188             _mChart.Invalidate();
189         }
190         /// <summary>
191         /// UI初始化
192         /// </summary>
193         private void _InitExampleUI()
194         {
195             //设置数据源
196             TaskGridView.DataSource = new BindingSource(_mManager.Tasks, null);
197             mnuFilePrint200.Click += (s, e) => _PrintDocument(2.0f);
198             mnuFilePrint150.Click += (s, e) => _PrintDocument(1.5f);
199             mnuFilePrint100.Click += (s, e) => _PrintDocument(1.0f);
200             mnuFilePrint80.Click += (s, e) => _PrintDocument(0.8f);
201             mnuFilePrint50.Click += (s, e) => _PrintDocument(0.5f);
202             mnuFilePrint25.Click += (s, e) => _PrintDocument(0.25f);
203             mnuFilePrint10.Click += (s, e) => _PrintDocument(0.1f);
204 
205             mnuFileImgPrint100.Click += (s, e) => _PrintImage(1.0f);
206             mnuFileImgPrint50.Click += (s, e) => _PrintImage(0.5f);
207             mnuFileImgPrint10.Click += (s, e) => _PrintImage(0.1f);            
208         }
209 
210         #region 菜单设置
211 
212         private void mnuFileSave_Click(object sender, EventArgs e)
213         {
214             using (var dialog = new SaveFileDialog())
215             {
216                 dialog.InitialDirectory = System.IO.Path.GetDirectoryName(Application.ExecutablePath);
217                 if (dialog.ShowDialog() == System.Windows.Forms.DialogResult.OK)
218                 {
219                     using (var fs = System.IO.File.OpenWrite(dialog.FileName))
220                     {
221                         System.Runtime.Serialization.Formatters.Binary.BinaryFormatter bf = new System.Runtime.Serialization.Formatters.Binary.BinaryFormatter();
222                        //序列化
223                         bf.Serialize(fs, _mManager);
224                     }
225                 }
226             }
227         }
228 
229         private void mnuFileOpen_Click(object sender, EventArgs e)
230         {
231             using (var dialog = new OpenFileDialog())
232             {
233                 dialog.InitialDirectory = System.IO.Path.GetDirectoryName(Application.ExecutablePath);
234                 if (dialog.ShowDialog() == System.Windows.Forms.DialogResult.OK)
235                 {
236                     using (var fs = System.IO.File.OpenRead(dialog.FileName))
237                     {
238                         System.Runtime.Serialization.Formatters.Binary.BinaryFormatter bf = new System.Runtime.Serialization.Formatters.Binary.BinaryFormatter();
239                         //反序列化
240                         _mManager = bf.Deserialize(fs) as ProjectManager;
241                         if (_mManager == null)
242                         {
243                             MessageBox.Show("Unable to load ProjectManager. Data structure might have changed from previous verions", "Gantt Chart", MessageBoxButtons.OK, MessageBoxIcon.Error);
244                         }
245                         else
246                         {
247                             _mChart.Init(_mManager);
248                             _mChart.Invalidate();
249                         }
250                     }
251                 }
252             }
253         }
254 
255         private void mnuFileExit_Click(object sender, EventArgs e)
256         {
257             this.Close();
258         }
259 
260         private void mnuViewDaysDayOfWeek_Click(object sender, EventArgs e)
261         {
262             _mManager.TimeScale = TimeScale.Day;
263             _mChart.TimeScaleDisplay = TimeScaleDisplay.DayOfWeek;
264             _mChart.Invalidate();
265         }
266 
267         private void mnuFileNew_Click(object sender, EventArgs e)
268         {
269             // start a new Project and init the chart with the project
270             _mManager = new ProjectManager();
271             _mManager.Add(new Task() { Name = "New Task" });
272             _mChart.Init(_mManager);
273             _mChart.Invalidate();
274         }
275 
276      
277 
278         private void mnuViewRelationships_Click(object sender, EventArgs e)
279         {
280             _mChart.ShowRelations = mnuViewRelationships.Checked = !mnuViewRelationships.Checked;
281             _mChart.Invalidate();
282         }
283 
284         private void mnuViewSlack_Click(object sender, EventArgs e)
285         {
286             _mChart.ShowSlack = mnuViewSlack.Checked = !mnuViewSlack.Checked;
287             _mChart.Invalidate();
288         }
289         /// <summary>
290         /// 甘特图快捷键说明
291         /// </summary>
292         /// <param name="sender"></param>
293         /// <param name="e"></param>
294         private void mnuViewIntructions_Click(object sender, EventArgs e)
295         {
296             _mOverlay.PrintMode = !(mnuViewIntructions.Checked = !mnuViewIntructions.Checked);
297             _mChart.Invalidate();
298         }
299 
300         #region Timescale Views
301         private void mnuViewDays_Click(object sender, EventArgs e)
302         {
303             _mManager.TimeScale = TimeScale.Day;
304             mnuViewDays.Checked = true;
305             mnuViewWeek.Checked = false;
306             _mChart.Invalidate();
307         }
308 
309         private void mnuViewWeek_Click(object sender, EventArgs e)
310         {
311             _mManager.TimeScale = TimeScale.Week;
312             mnuViewDays.Checked = false;
313             mnuViewWeek.Checked = true;
314             _mChart.Invalidate();
315         }
316 
317         private void mnuViewDayOfWeek_Click(object sender, EventArgs e)
318         {
319             _mChart.TimeScaleDisplay = TimeScaleDisplay.DayOfWeek;
320             mnuViewDayOfWeek.Checked = true;
321             mnuViewDayOfMonth.Checked = false;
322             mnuViewWeekOfYear.Checked = false;
323             _mChart.Invalidate();
324         }
325 
326         private void mnuViewDayOfMonth_Click(object sender, EventArgs e)
327         {
328             _mChart.TimeScaleDisplay = TimeScaleDisplay.DayOfMonth;
329             mnuViewDayOfWeek.Checked = false;
330             mnuViewDayOfMonth.Checked = true;
331             mnuViewWeekOfYear.Checked = false;
332             _mChart.Invalidate();
333         }
334 
335         private void mnuViewWeekOfYear_Click(object sender, EventArgs e)
336         {
337             _mChart.TimeScaleDisplay = TimeScaleDisplay.WeekOfYear;
338             mnuViewDayOfWeek.Checked = false;
339             mnuViewDayOfMonth.Checked = false;
340             mnuViewWeekOfYear.Checked = true;
341             _mChart.Invalidate();
342         }
343         #endregion Timescale Views
344 
345         #endregion Main Menu
346 
347         #region Sidebar
348 
349         private void _mDateTimePicker_ValueChanged(object sender, EventArgs e)
350         {
351             _mManager.Start = _mStartDatePicker.Value;
352             var span = DateTime.Today - _mManager.Start;
353             _mManager.Now = (int)Math.Round(span.TotalDays);
354             if (_mManager.TimeScale == TimeScale.Week) _mManager.Now = (_mManager.Now % 7) * 7;
355             _mChart.Invalidate();
356         }
357 
358         private void _mPropertyGrid_SelectedGridItemChanged(object sender, SelectedGridItemChangedEventArgs e)
359         {
360             _mChart.Invalidate();
361         }
362 
363         private void _mNowDatePicker_ValueChanged(object sender, EventArgs e)
364         {
365             TimeSpan span = _mNowDatePicker.Value - _mStartDatePicker.Value;
366             _mManager.Now = span.Days + 1;
367             if (_mManager.TimeScale == TimeScale.Week) _mManager.Now = _mManager.Now / 7 + (_mManager.Now % 7 > 0 ? 1 : 0);
368             _mChart.Invalidate();
369         }
370 
371         private void _mScrollDatePicker_ValueChanged(object sender, EventArgs e)
372         {
373             _mChart.ScrollTo(_mScrollDatePicker.Value);
374             _mChart.Invalidate();
375         }
376 
377         private void _mTaskGridView_SelectionChanged(object sender, EventArgs e)
378         {
379             if (TaskGridView.SelectedRows.Count > 0)
380             {
381                 var task = TaskGridView.SelectedRows[0].DataBoundItem as Task;
382                 _mChart.ScrollTo(task);
383             }
384         }
385 
386         #endregion Sidebar
387 
388         #region 打印设置
389 
390         private void _PrintDocument(float scale)
391         {
392             using (var dialog = new PrintDialog())
393             {
394                 dialog.Document = new System.Drawing.Printing.PrintDocument();
395                 if (dialog.ShowDialog() == System.Windows.Forms.DialogResult.OK)
396                 {
397                     // set the print mode for the custom overlay painter so that we skip printing instructions
398                     dialog.Document.BeginPrint += (s, arg) => _mOverlay.PrintMode = true;
399                     dialog.Document.EndPrint += (s, arg) => _mOverlay.PrintMode = false;
400 
401                     // tell chart to print to the document at the specified scale
402                     _mChart.Print(dialog.Document, scale);
403                 }
404             }
405         }
406 
407         private void _PrintImage(float scale)
408         {
409             using (var dialog = new SaveFileDialog())
410             {
411                 dialog.Filter = "Bitmap (*.bmp) | *.bmp";
412                 if (dialog.ShowDialog() == System.Windows.Forms.DialogResult.OK)
413                 {
414                     // set the print mode for the custom overlay painter so that we skip printing instructions
415                     _mOverlay.PrintMode = true;
416                     // tell chart to print to the document at the specified scale
417 
418                     var bitmap = _mChart.Print(scale);
419                     _mOverlay.PrintMode = false; // restore printing overlays
420 
421                     bitmap.Save(dialog.FileName, System.Drawing.Imaging.ImageFormat.Bmp);
422                 }
423             }
424         }
425 
426         #endregion Print        
427 
428         private void ExampleFull_Load(object sender, EventArgs e)
429         {
430 
431         }
432 
433         
434     }
435 
436     #region overlay painter
437     /// <summary>
438     /// An example of how to encapsulate a helper painter for painter additional features on Chart
439     /// </summary>
440     public class OverlayPainter
441     {
442         /// <summary>
443         /// Hook such a method to the chart paint event listeners
444         /// </summary>
445         /// <param name="sender"></param>
446         /// <param name="e"></param>
447         public void ChartOverlayPainter(object sender, ChartPaintEventArgs e)
448         {
449             // Don't want to print instructions to file
450             if (this.PrintMode) return;
451 
452             var g = e.Graphics;
453             var chart = e.Chart;
454 
455             // Demo: Static billboards begin -----------------------------------
456             // Demonstrate how to draw static billboards
457             // "push matrix" -- save our transformation matrix
458             e.Chart.BeginBillboardMode(e.Graphics);
459 
460             // draw mouse command instructions
461             int margin = 300;
462             int left = 20;
463             var color = chart.HeaderFormat.Color;
464             StringBuilder builder = new StringBuilder();
465             builder.AppendLine("THIS IS DRAWN BY A CUSTOM OVERLAY PAINTER TO SHOW DEFAULT MOUSE COMMANDS.");
466             builder.AppendLine("*******************************************************************************************************");
467             builder.AppendLine("Left Click - Select task and display properties in PropertyGrid");
468             builder.AppendLine("Left Mouse Drag - Change task starting point");
469             builder.AppendLine("Right Mouse Drag - Change task duration");
470             builder.AppendLine("Middle Mouse Drag - Change task complete percentage");
471             builder.AppendLine("Left Doubleclick - Toggle collaspe on task group");
472             builder.AppendLine("Right Doubleclick - Split task into task parts");
473             builder.AppendLine("Left Mouse Dragdrop onto another task - Group drag task under drop task");
474             builder.AppendLine("Right Mouse Dragdrop onto another task part - Join task parts");
475             builder.AppendLine("SHIFT + Left Mouse Dragdrop onto another task - Make drop task precedent of drag task");
476             builder.AppendLine("ALT + Left Dragdrop onto another task - Ungroup drag task from drop task / Remove drop task from drag task precedent list");
477             builder.AppendLine("SHIFT + Left Mouse Dragdrop - Order tasks");
478             builder.AppendLine("SHIFT + Middle Click - Create new task");
479             builder.AppendLine("ALT + Middle Click - Delete task");
480             builder.AppendLine("Left Doubleclick - Toggle collaspe on task group");
481             var size = g.MeasureString(builder.ToString(), e.Chart.Font);
482             var background = new Rectangle(left, chart.Height - margin, (int)size.Width, (int)size.Height);
483             background.Inflate(10, 10);
484             g.FillRectangle(new System.Drawing.Drawing2D.LinearGradientBrush(background, Color.LightYellow, Color.Transparent, System.Drawing.Drawing2D.LinearGradientMode.Vertical), background);
485             g.DrawRectangle(Pens.Brown, background);
486             g.DrawString(builder.ToString(), chart.Font, color, new PointF(left, chart.Height - margin));
487 
488             
489             // "pop matrix" -- restore the previous matrix
490             e.Chart.EndBillboardMode(e.Graphics);
491             // Demo: Static billboards end -----------------------------------
492         }
493 
494         public bool PrintMode { get; set; }
495     }
496     #endregion overlay painter
497 
498     #region 自定义任务和资源类
499     /// <summary>
500     ///自定义资源
501     /// </summary>
502     [Serializable]
503     public class MyResource
504     {
505         public string Name { get; set; }
506     }
507     /// <summary>
508     /// 自定义任务类,继承 Task 接口 (可选)
509     /// </summary>
510     [Serializable]
511     public class MyTask : Task
512     {
513         public MyTask(ProjectManager manager) : base()
514         {
515             Manager = manager;
516         }
517 
518         private ProjectManager Manager { get; set; }
519 
520         public new int Start { get { return base.Start; } set { Manager.SetStart(this, value); } }
521         public new int End { get { return base.End; } set { Manager.SetEnd(this, value); } }
522         public new int Duration { get { return base.Duration; } set { Manager.SetDuration(this, value); } }
523         public new float Complete { get { return base.Complete; } set { Manager.SetComplete(this, value); } }
524     }
525     #endregion 
526 }

 

原文地址:https://www.cnblogs.com/isaboy/p/gantt.html