c# - 如何在 WFP C#.Net 中拆分相交标签?
问题描述
我创建了这个 WFP 应用程序,它在表单的某些位置生成标签,以显示基于其他表单设置的每周计划
CustomLabel.Add(new Label()):
(CustomLabel[CustomLabel.Count - 1] as Label).Location = new System.Drawing.Point(117,Y(LISTPLANS[MainForm.indexplan].Subjects.ElementAt<Subject(i).PSchedule.StartTime));
(CustomLabel[CustomLabel.Count - 1] as Label).Size = new System.Drawing.Size(97,L(LISTPLANS[MainForm.indexplan].Subjects.ElementAt<Subject(i).PSchedule.StartTime,LISTPLANS[MainForm.indexplan].Subjects.ElementAt<Subject>(i).PSchedule.EndTime));
Controls.Add(CustomLabel[CustomLabel.Count - 1] as Control);
标签的大小和位置相对于开始日期时间和结束日期时间,当然还有日期:
public Int32 Y(DateTime StartTime)
{
double onehour = 19.5;
double minute = Math.Ceiling(StartTime.Minute / 15.0) / 4.0;
switch (StartTime.Hour)
{
case 6:
return (Int32)(94 + minute * onehour);
case 7:
return (Int32)(114 + minute * onehour);
case 8:
return (Int32)(135 + minute * onehour);
case 9:
return (Int32)(156 + minute * onehour);
case 10:
return (Int32)(177 + minute * onehour);
case 11:
return (Int32)(197 + minute * onehour);
case 12:
return (Int32)(219 + minute * onehour);
case 13:
return (Int32)(240 + minute * onehour);
case 14:
return (Int32)(260 + minute * onehour);
case 15:
return (Int32)(280 + minute * onehour);
case 16:
return (Int32)(302 + minute * onehour);
case 17:
return (Int32)(322 + minute * onehour);
case 18:
return (Int32)(344 + minute * onehour);
case 19:
return (Int32)(366 + minute * onehour);
case 20:
return (Int32)(388 + minute * onehour);
case 21:
return (Int32)(407 + minute * onehour);
case 22:
return (Int32)(428 + minute * onehour);
case 23:
return (Int32)(449 + minute * onehour);
case 0:
return (Int32)(470 + minute * onehour);
default:
return 0;
}
}
public Int32 L(DateTime StartTime, DateTime EndTime)
{
return (Int32)(Y(EndTime) - Y(StartTime));
}
我想通了,但问题仍然是如果用户输入的时间类似于先前保留的时间,程序将在旧的蚂蚁上创建一个标签,它将隐藏它,如果用户设置例如:Subject1:从 8: 00 -> 11:00 - 星期六 Subject2 : 从 10:00 -> 12:00 - 星期六 生成的两个标签将相互交叉。我想要一个分割这些相交标签的代码(默认宽度为 97),以便两者的宽度都为 48:
解决方案
您需要首先将重叠的分组。这是一个例子来说明这个想法。
static IEnumerable<RectangleF> Layout(IEnumerable<(DateTime StartTime, DateTime EndTime)> source, SizeF area)
{
static bool Overlaps(
(DateTime StartTime, DateTime EndTime) a,
(DateTime StartTime, DateTime EndTime) b) =>
a.StartTime <= b.StartTime && a.EndTime > b.StartTime ||
a.StartTime <= b.EndTime && a.EndTime > b.EndTime;
var set = new HashSet<(DateTime StartTime, DateTime EndTime)>();
IEnumerable<RectangleF> results =
from item in source
let matches = source.Where(x => Overlaps(item, x) && set.Add(x)).ToList()
from t in matches.Select((match, index) => (match, index))
let y = t.match.StartTime.TimeOfDay.Ticks / TimeSpan.TicksPerDay * area.Height
let height = (t.match.EndTime - t.match.StartTime).Ticks / TimeSpan.TicksPerDay * area.Height
let x = t.index * 1f / matches.Count / area.Width
let width = 1f / matches.Count * area.Width
select new RectangleF(x, y, width, height);
return results;
}
推荐阅读
- postgresql - 在 postgresql 中创建大对象
- reactjs - React 图像源不需要读取变量
- c++ - C++17 编译器不应该发现对未定义值的传递引用吗?
- c# - ASP.Net MVC 5 - 在控制器外部访问 HttpContext.Current.User 的正确方法?
- solr - 禁用 solr 健康检查的日志
- c++ - 防止向量使类的所有实例相同
- elasticsearch - 如何在不停机的情况下更改弹性搜索集群中现有节点的节点类型(数据、主节点或客户端)?
- google-app-maker - 使用 App Maker 在 Google Docs 中创建表格
- c++ - 找到两个链表的合并点?
- sql - SQL 查询根据特定列值以及插入的降序日期过滤记录