.Net TableLayoutPanel-очистка элементов управления очень медленная
Это очень просто.
У меня есть TableLayoutPanel, который заполнен элементами управления (только метки, кнопки и некоторые панели с кнопками) на основе запроса базы данных. Когда данные необходимо обновить, я использую TableLayoutPanel.Контроли.Четкий.)( К сожалению, это очень медленная операция. Я ожидал бы, что он будет быстрее, чем код, заполняющий таблицу, но он по крайней мере в 3 или 4 раза медленнее.
Я окончательно доказал, что медлительность при выполнении Контроли.Clear (), выполнив это как единственное, что сделано в TableLayoutPanel после отображения окна сообщения (затем процедура возвращается). Элементы управления заметно исчезают снизу вверх. Когда набор записей используется для повторного заполнения TableLayoutPanel, скорость элементов управления, появляющихся сверху вниз, почти быстрее, чем я могу видеть.
Я уже делаю TableLayoutPanel.SuspendLayout() и ResumeLayout().
С помощью this.DoubleBuffered = true
на форме не представляется сделать ничего.
Я мог бы просто утилизировать весь элемент управления и воссоздать его с помощью кода, но это большая боль и делает бессмысленным хороший графический интерфейс дизайнера форм. Мне пришлось бы копаться в каждом свойстве, которое я установил на элементе управления, и создать строку кода для него (хотя я думаю, что мог бы получить это из самого кода дизайнера, он все еще чувствует себя неправильно).
любые идеи о том, как делать работу быстрее? Я даже открыт для использования других методов, кроме TableLayoutPanel... Мне просто нужно свобода размещения нескольких кнопок на ячейку или запрет, чтобы иметь возможность охватывать столбцы в заголовке таблицы.
может ли C# по крайней мере заморозить всю форму, пока она перерисовывается, а затем рисовать все сразу?
4 ответов
я столкнулся с проблемами с медлительностью, используя TableLayoutPanels. Вместо установки свойства DoubleBuffered в форме лучшим решением, которое я нашел, является создание нового класса, наследующего от TableLayoutPanel, и в конструкторе этого класса включите двойную буферизацию:
public class DoubleBufferedTableLayoutPanel : TableLayoutPanel
{
public DoubleBufferedTableLayoutPanel()
{
DoubleBuffered = true;
}
}
затем используйте DoubleBufferedTableLayoutPanel везде, где вы обычно используете TableLayoutPanel.
Это, кажется, работает для моей пользы:
tableLayoutPanel.Visible = false;
tableLayoutPanel.Clear();
/* Add components to it */
tableLayoutPanel.Visible = true;
нет необходимости в подклассе TableLayoutPanel
а в ответ Криса Райана. У меня была такая же проблема и я решил ее, установив свойство через отражение:
typeof(TableLayoutPanel)
.GetProperty("DoubleBuffered",
System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.Instance)
.SetValue(myTableLayoutPanel, true, null);
если я собираюсь создать какой-то динамический gui, я всегда буду делать это в коде. Но в начальной точке я просто начинаю с дизайнера по фиктивной форме и стилю каждого элемента управления так, как мне (или лучше клиенту) нравится(ы). Потом я смотрю на дизайнера.cs-файл и скопируйте необходимые настройки свойств из него в некоторую заводскую функцию, такую как
private TextBox CreateTextBox(string name, /* maybe other parameters */)
{
var textBox = new TextBox();
textBox.Name = name;
//Other settings from given parameters...
//Further settings which are all the same for these kind of control
textBox.KeyDown += (sender, e) => {};
return textBox;
}
поэтому я убеждаюсь, что каждый элемент управления чувствует и выглядит одинаково на моем GUI. Это будет сделано на каждом уровне внутри моего поверхность (начиная с небольших элементов управления, таких как TextBox
и подходит к контейнерам, как GroupBox
или TableLayoutPanel
.
в некоторых случаях это приводит к точке, где заводская функция вызывает несколько других заводских функций. Если это становится правдой, пришло время подумать о инкапсуляции этих элементов управления в один UserControl
, но как всегда зависит если это необходимо или нет.
С моей стороны я могу только поощрять вас к перемещению кода из конструктора в самописную функцию. В начале это (как всегда) больше работы, но после этого легче внести еще большие изменения в макет.