У меня есть окно, которое выполняет какой-то процесс с визуализацией. И мне надо чтобы при запуске приложение оно работало, но не показывалось (то есть чтобы произошло событие Load
). При этом у пользователя всегда есть возможность его показывать и скрывать. Проблема в том что у меня не получается решить этот вопрос без начального мерцания из-за подобного кода.
SomeWindow.Show();
SomeWindow.Hide();
Ни в Windows Forms, ни в WPF не вижу решения этой проблемы.
Проблема также в том, что окно показывается в TaskBar, но только когда оно видимое. Поэтому мне не подходят хаки вроде
Для чего это надо и почему нельзя всё вынести в какой-нибудь Task
? Потому что код выполняемый окном зависит от визуализации. Мне нужно чтобы человек мог скрывать и показывать окно когда и сколько угодно, но чтобы его состояние было таким же как будто его не скрывали.
Просто так вам не получится вызвать событие Loaded
: оно вызывается лишь тогда, когда ваше окно реально было показано. Но, возможно, у вас сработает обходной путь, который сработал в моём проекте.
Для начала, мы отделим контент окна в UserControl
. Окно пусть будет пустым. Контрол назовём SimpleUserControl
для примера.
Теперь мы в начале работы приложения создаём контрол, но не показываем его, таким образом:
public partial class App : Application
{
protected override async void OnStartup(StartupEventArgs e)
{
base.OnStartup(e);
var uc = new SimpleUserControl(); // создали контрол
// возможно, надо установить DataContext
var size = new Size(100, 100); // фейковый размер
uc.Measure(size); // заставляем пробежать layout engine
uc.Arrange(new Rect(size));
uc.UpdateLayout();
// дождёмся выполнения пустой лямбды на фоновом приоритете,
// это даст время привязкам разрешиться
await Dispatcher.CurrentDispatcher.InvokeAsync(
() => { },
DispatcherPriority.Background);
// теперь можно работать с контролом. я просто сделаю паузу для примера
await Task.Delay(9000);
// и вставить его в окно:
new MainWindow() { Content = uc }.Show();
}
}
При этом Loaded
на контроле всё ещё не вызывается (оно вызовется только при показе), но у вас подконтролы будут находиться в «рабочем» состоянии.
Получил ответ на англ. SO. Этот же код работает для WPF если заменить FormWindowState
на WindowState
. Суть в том, что надо сначала чтобы перед "показом" установить (в коде или дизайнере):
SomeWindow.ShowInTaskbar = false;
SomeWindow.WindowState = FormWindowState.Minimized;
Затем выполнить код
SomeWindow.Show();
SomeWindow.Hide();
И сразу после этого подготавливаем окно для нормального отображения при последующих вызовах SomeWindow.Show
:
SomeWindow.ShowInTaskbar = true; // Если надо чтобы форма показывалась на панели быстого запуска.
SomeWindow.WindowState = FormWindowState.Normal; // или FormWindowState.Maximized если надо
Это можно превратить в метод расширения для Windows Forms:
public static class FormHelper
{
public static void ShowInvisible(this Form form)
{
// сохраняем параметры окна
bool needToShowInTaskbar = form.ShowInTaskbar;
WindowState initialWindowState = form.WindowState;
// делаем окно невидимым
form.ShowInTaskbar = false;
form.WindowState = FormWindowState.Minimized;
// показываем и скрываем окно
form.Show();
form.Hide();
// восстанавливаем параметры окна
form.ShowInTaskbar = needToShowInTaskbar;
form.WindowState = initialWindowState;
}
}
или для WPF:
public static class WindowHelper
{
public static void ShowInvisible(this Window window)
{
// сохраняем параметры окна
bool needToShowInTaskbar = window.ShowInTaskbar;
WindowState initialWindowState = window.WindowState;
// делаем окно невидимым
window.ShowInTaskbar = false;
window.WindowState = WindowState.Minimized;
// показываем и скрываем окно
window.Show();
window.Hide();
// восстанавливаем параметры окна
window.ShowInTaskbar = needToShowInTaskbar;
window.WindowState = initialWindowState;
}
}
Как я понял, при создании формы:
Load
,По-моему, установка прозрачности в ноль перед показом, а после показа в единицу полностью решает проблему.
var form = new Form();
form.Opacity = 0;
form.Load += Form_Load;
form.Show();
form.WindowState = FormWindowState.Minimized;
form.Opacity = 1;
Событие вызывается, форма не мелькает, на таскбаре отображается.
Айфон мало держит заряд, разбираемся с проблемой вместе с AppLab
Перевод документов на английский язык: Важность и ключевые аспекты
Всем доброе время суток! Можно ли реализовать отрисовку различных фигур на каком-то элементе управления, для примера этот: <lvc:CartesianChart GridColumn="1"...
Есть в других IDE такая функция, которая предлагает название переменной исходя из ее типаПример: