Как разделить пересекающиеся метки в WFP C#. Net? - PullRequest
0 голосов
/ 03 апреля 2020

Я создал это приложение 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);

Размер и расположение метки относительно начального DateTime и конечного DateTime и, конечно, Day:

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:

Результат

1 Ответ

0 голосов
/ 03 апреля 2020

Сначала вам нужно сгруппировать перекрывающиеся. Вот пример, иллюстрирующий эту идею.

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;
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...