Как эффективно визуализировать нетривиальную (динамическое количество столбцов и строк, графических и управляющих элементов в ячейках ...) сетку в C #? - PullRequest
0 голосов
/ 29 апреля 2019

Sumary

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

1

Большинство элементов поддерживает щелчок левой / правой кнопкой мыши, показывает всплывающие подсказки при вводе мыши и элементы встроки календаря (это рабочие фазы производственного плана) также поддерживают перетаскивание и синхронизацию с базой данных (локально, связь с Entity Framework).

Количество строк основано на количестве проектов в заданном интервале времени и, таким образом,динамичный.Я также хотел бы, чтобы число столбцов (дней) было динамическим, и пользователь мог установить свой собственный временной интервал, но это не требуется.

Проблема в том, что, хотя я считаю, что результат очень хороший,Я был (все еще) совершенно неопытен, когда начал проект, и результат медленный (+ - 3 секунды рендеринга для 20 строк - на практике я всегда работаю с не более чем 25 строками). Это из-за моего плохого дизайна. Ховевер, я не знаю, как добиться схожих результатов с более высокой производительностью.

Я уверен, что проблема в рендеринге

Я попробовал профилировщик (тот, что с Visual Studio / Resharper) и подтвердил, что проблема заключается в плохом дизайне визуализации внешнего интерфейса.SQL-запросы работают около 20 мс, методы, которые создают и отображают строки за 3 секунды.Я также попытался упростить данные (без графических элементов, только строки без упомянутой выше функциональности) и поместить их в DataGrid - результат не задерживался примерно до 70 строк, что намного больше, чем мне нужно.

Не удалось найти решение

Я потратил 3 дня на поиск и переработку своего кода, но не нашел решения, действительно полезного для моего случая.Самым близким, что я получил, был ответ wpf DataGrid из UserControls с помещением пользовательских контролов в сетку данных.Однако результат не выглядел так же хорошо, как текущее состояние, и, что более важно, для меня оказалось почти невозможным правильно связать пользовательский контроль с объектами базы данных.

Вот метод, который стоит мне больше всего производительности:

private void RenderFull()
{
   // prepare columns
   columns.Clear();
   columnForDate.Clear();

   ColumnJobHeader columnJob = new ColumnJobHeaderClassic(job);
   columnJob.JobUpdated += ColumnJob_JobUpdated;
   columnJob.JobDeleted += ColumnJob_JobDeleted;
   columns[0] = columnJob;

   DateTime processedDate = startDate;
   while (processedDate <= endDate)
   {
       ColumnJobDay col = new ColumnJobDay(job, processedDate, startDate, endDate);
       columns[columns.Count] = col;
       columnForDate[processedDate] = col;
       col.PhaseChanged += Handler_PhaseChanged;
       processedDate = processedDate.AddDays(1);
   }

   // remove rendered columns
   RemoveRenderedColumns();

   // render new columns
   RenderColumns();
}

Это подготавливает все столбцы в базе данных с проектами (строка 6+).Затем они генерируются в этом методе (AbstractColumn is UserControl):

public override void RenderColumns()
{
   foreach (KeyValuePair<int, AbstractColumn> pair in columns)
   {
      ColumnDefinition columnDefinition = new ColumnDefinition();
      if (pair.Value is ColumnJobHeader)
         columnDefinition.Width = new GridLength(200);
      Columns.ColumnDefinitions.Add(columnDefinition);
      pair.Value.SetValue(Grid.ColumnProperty, pair.Key);
      Columns.Children.Add(pair.Value);
   }
   Wrapper.Child = Columns;
}

Я знаю, что создание представления в коде, как это плохо, для дизайна и производительности, и я могу обещать, что я усвоил урок, чтобы никогда не делатьэто снова.Тем не менее, я понятия не имею, как добиться такого приложения с правильным дизайном.

Я ценю любой совет.Заранее спасибо, ребята!

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...