Загрузить форму, не показывая ее - PullRequest
11 голосов
/ 16 сентября 2008

Короткая версия: я хочу вызвать событие Form_Load (), не делая форму видимой. Это не работает, потому что Show () игнорирует текущее значение свойства Visible:

tasksForm.Visible = false;
tasksForm.Show();

Длинная версия: у меня есть приложение WinForms с двумя формами: основной и задач. Основная форма всегда отображается. Пользователь может либо нажать кнопку, чтобы открыть форму задач, либо щелкнуть несколько кнопок, которые просто запускают задачу напрямую, не открывая форму задач.

Когда пользователь просит запустить задачу напрямую, я хотел бы просто вызвать некоторые открытые методы в форме задач, не показывая ее. К сожалению, логика задачи зависит от того, что происходит в событии Form_Load (). Единственный способ найти Form_Load () - это вызвать Show (). Лучшее, что я смог сделать, это показать форму в свернутом состоянии:

tasksForm.WindowState = FormWindowState.Minimized;
tasksForm.Show();

Полагаю, самым чистым решением было бы вытащить логику задач из формы задач в класс контроллера. Затем я могу использовать этот класс из основной формы и из формы задач и загружать форму задач только тогда, когда она мне нужна для просмотра. Однако, если загрузить форму без ее отображения просто, это будет меньшее изменение.

Ответы [ 8 ]

15 голосов
/ 10 декабря 2010

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

В любом случае, хороший дизайн или нет, вы можете сделать это так:

MyForm f = new MyForm();
IntPtr dummy = f.Handle; // forces the form Control to be created

Я не думаю, что это вызовет вызов Form_Load (), но вы сможете вызвать f.Invoke () в этот момент (именно это я и пытался сделать, когда наткнулся на этот вопрос SO) .

8 голосов
/ 16 сентября 2008

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

6 голосов
/ 16 сентября 2008

Я полностью согласен с Rich B, вам нужно смотреть на то, где вы размещаете логику своего приложения, а не пытаться заглушить механизмы WinForms. Все те операции и данные, которые предоставляет ваша форма «Задачи», на самом деле должны быть в отдельном классе, скажем, какой-то Application Controller или что-то, хранящееся в вашей главной форме, а затем использоваться вашей формой задач для чтения и отображения данных при необходимости, но не нужна форма, чтобы быть созданным для существования.

Возможно, его переделка кажется трудной, но вы улучшите структуру приложения и сделаете его более удобным для обслуживания и т. Д.

5 голосов
/ 16 сентября 2008

Из MSDN:

Form.Load
Происходит до того, как форма отображается в первый раз.

Это означает, что единственное, что может привести к загрузке формы, это когда она отображается.
Form.Show(); и Form.Visible = true; - это одно и то же. По сути, за кулисами «Показать» проверяет различные условия, а затем устанавливает для параметра «Видимый» значение true. Очевидно, что установка видимого в false (который уже есть) перед показом формы не имеет смысла.

Но давайте забудем о технических деталях. Я полностью согласен с Ричем Б. и Шоном Остином - логика не должна быть в такой форме.

1 голос
/ 12 сентября 2013

Иногда это было бы полезно без плохого дизайна. Иногда это может быть началом перехода с нативного на управляемый.

Если вы, например, мигрировали приложение c ++ в .NET, вы можете просто сделать свое приложение дочерним окном формы или панели .NET и постепенно мигрировать в .NET, избавившись от меню приложения c ++, строка состояния, панель инструментов и отображение .Net из вашего приложения с помощью вызова платформы и т.д ...

Вашему приложению C ++ может потребоваться некоторое время для загрузки, но форма .NET не… в которой вы можете скрыть форму .NEt до тех пор, пока ваше приложение c ++ не инициализирует себя.

Я бы установил opacity = 0 и visible = false в false после вызова show, затем, когда загрузится ваше приложение на c ++, затем наоборот.

0 голосов
/ 22 августа 2018

Ни один из ответов не решил исходный вопрос, поэтому добавьте нижеприведенный код, вызовите .Show (), чтобы загрузить форму, не показывая ее, а затем вызовите .ShowForm (), чтобы она была видна, если вы хотите после: 1001 *

private volatile bool _formVisible;
protected override void SetVisibleCore(bool value)
{
    base.SetVisibleCore(_formVisible);
}
public void ShowForm()
{
    _formVisible = true;
    if (InvokeRequired)
    {
        Invoke((Action) Show);
    }
    else
    {
        Show();
    }
}
0 голосов
/ 16 сентября 2008

Переместите код обязательной инициализации для класса формы из обработчика события Load в конструктор. Для класса Form создание экземпляра экземпляра (через конструктор), загрузка формы и видимость формы - три разные вещи, и они не должны происходить одновременно (хотя они, очевидно, должны происходить в таком порядке) 1002 *

0 голосов
/ 16 сентября 2008

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

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