WPF甘特图开发:如何将最早开始日期的工作包矩形放在首位
实现方法
你不需要自己手写循环查找最早日期,直接对workpackages数组按开始日期升序排序后再遍历绘制即可,同时需要修正原代码中矩形左偏移的计算逻辑,才能正确体现每个工作包的开始时间位置:
- 首先对工作包数组排序
可以直接用内置排序方法,无需自行实现日期比较逻辑:
// 方法1:使用LINQ排序(需先引用命名空间 using System.Linq;) var sortedWorkPackages = workpackages.OrderBy(p => p.startdate).ToArray(); // 方法2:无LINQ的原生排序写法 Array.Sort(workpackages, (a, b) => a.startdate.CompareTo(b.startdate)); // 排序后原workpackages数组已经是按开始日期升序排列,最早的在索引0位置
- 修正绘制逻辑
排序后遍历排序后的数组绘制即可,同时修正矩形左偏移的计算:
// 拿排序后第一个的开始日期作为时间轴起点 var earliestStart = sortedWorkPackages[0].startdate; double dayToPixelRatio = 1; // 如果你需要调整时间轴缩放可以改这个值,1代表1天对应1像素 for (int i = 0; i < sortedWorkPackages.Length; i++) { var currentPackage = sortedWorkPackages[i]; double totalDays = (currentPackage.enddate - currentPackage.startdate).TotalDays; double leftOffset = (currentPackage.startdate - earliestStart).TotalDays * dayToPixelRatio; Rectangle rectangle = new Rectangle { Fill = brush, StrokeThickness = strokethickness, Stroke = Brushes.Black, Width = totalDays * dayToPixelRatio, Height = rectangleHeight / howmanyrect - distancebetweenrectangles }; MyRectangle[i] = rectangle; // 按时间差计算左偏移,不再是固定靠左 Canvas.SetLeft(rectangle, leftOffset); // 按排序后的索引计算Top位置,最早的工作包自然在最上方第一行 Canvas.SetTop(rectangle, i * (rectangleHeight / howmanyrect)); myCanvas.Children.Add(rectangle); } // Content赋值只需要做一次,不需要放在循环里 Content = myCanvas;
补充说明
原代码中Canvas.SetLeft(rectangle, rectangle.Width / 2.0 - rectangle.Width / 2.0)的计算结果恒为0,所有矩形都会靠左对齐,无法体现开始日期的先后差异,修正后按和最早开始日期的时间差计算左偏移,才能得到符合甘特图规则的时间排布效果。
内容的提问来源于stack exchange,提问作者Connor
相关产品推荐
相关产品推荐

