2011-01-12 4 views
12

У меня есть многослойная форма, на левой панели есть дерево, а в правой панели - панель. Выбор дерева приводит к тому, что определенные пользовательские элементы управления загружаются на Panel. В этом случае, поскольку родительская форма всегда загружается, я не могу подключиться к событию Shown родительской формы.Как вызвать метод в UserControl после его отображения?

Большинство моих UC имеют несвязанный DataGridView на них, который необходимо заполнить при создании UC. Время от времени может быть установлено 50 000 строк из базы данных SQL Server.

До сих пор я заполнял сетки во время конструктора UC, но так как мы начали работать с 50 000 строк, все изменилось. Я обнаружил, что заполнение сетки 50 000 строк от конструктора занимает не менее 15 минут по какой-то сумасшедшей причине. Однако, если я жду, чтобы заполнить сетку, пока я не нажму кнопку или из события загрузки, это займет 15 секунд. Это тайна. Поэтому я пытаюсь переместить загрузку сетки в другое место.

Однако, когда я пытаюсь заполнить сетку из события Load, есть визуальные несоответствия. Что произойдет, вы видите, что появляется небольшая версия моего UC, для загрузки строк DGV требуется 15 секунд, а ТОЛЬКО UC расширяется, чтобы заполнить панель (для свойства UC Dock установлено значение Fill). Поэтому мне тоже не нравится этот вариант.

Событие Shown было бы идеальным местом для загрузки моей сетки, если бы оно существовало для UC. Кто-нибудь знает, как это сделать?

+1

Лучше вопрос, почему она занимает 15 минут, чтобы загрузить в конструкторе, но 15 секунд в другом месте. – Justin

+1

Наверное, потому что его логика численности населения выполняется на основе чего-то, что многократно менялось при построении формы, или он кэширует загрузку нескольких DGV при загрузке формы. – KeithS

+0

Идеи приветствуются, почему это происходит. Я бы предпочел остаться с моим прежним подходом. Код состоит из вызова базы данных (данные не меняются) и заполнения одного DGV. Существует разница между вызовом из конструктора и вызовом с кнопки - конструктор вызывается изнутри потока BackgroundWorker. Может ли это быть причиной этого? –

ответ

16

Мой ответ на аналогичную проблему состоял в том, чтобы заполнить DGV, когда сетка стала видимой. В этом суть ленивой нагрузки; получить информацию в последнюю возможную секунду.

Захват в VisibleChanged, который будет срабатывать, когда ваш элемент управления имеет Show() или Hide(), или свойство Visible, заданное вручную. Если поле в настоящее время видимо, И элемент управления не находится в процессе закрытия или размещения (потому что для некоторых причудливых причин элементы управления могут стать видимыми в этом случае), выполните свою сетку.

Вот необходимый обработчик, очень прост:

protected override void OnVisibleChanged(EventArgs e) 
{ 
    base.OnVisibleChanged(e); 

    if (Visible && !Disposing) PopulateGridView(); //<-- your population logic 
} 
+0

Спасибо, я уверен, что это сработает для UC с статическим размером, однако, когда я попробую с моим UC, что Docks «Full» в его контейнере, сетка заполняется до того, как UC будет изменена, чтобы соответствовать контейнеру, в результате чего некоторые плавающие в полосах прокрутки в течение 15 секунд, чтобы загрузить сетку. Я нашел способ загрузить сетку, хотя, вызвав метод после загрузки UC (нужно использовать ugh DoEvents, чтобы он был первым!). –

+0

Его близкое к тому, что я хочу, но теперь это время загрузки происходит за пределами BackgroundWorker, и графический интерфейс становится менее отзывчивым (потенциальный (не реагирующий), который я ненавижу). Это может быть моим лучшим решением. –

+0

Huh. Мои UC с gridviews также заполнены. Попробуйте использовать SuspendLayout и ResumeLayout, чтобы приостановить позиционирование элементов окна до тех пор, пока население не будет завершено.Чтобы решить проблему, не отвечающую на запросы, вы можете настроить свой пользовательский элемент управления с помощью делегата и обработчика событий, который будет взаимодействовать с асинхронной процедурой заполнения. Попросите UC начать метод BeginPopulate, подпишитесь на событие PopulateComplete и выполните свою работу по заполнению сетки от этого обработчика. – KeithS

Смежные вопросы