Question:
I have a window that is doing some kind of rendering process. And I need that when the application starts, it works, but is not shown (that is, so that the Load
event occurs). At the same time, the user always has the ability to show and hide it. The problem is that I can't solve this issue without the initial flickering due to this code.
SomeWindow.Show();
SomeWindow.Hide();
Neither Windows Forms nor WPF see a solution to this problem.
The problem is also that the window is shown in the TaskBar, but only when it is visible. Therefore, hacks like
- Window transparency settings.
- Zero Latitude, Altitude and Frame Removal Settings.
- Moving the window out of the screen, etc.
Why is this necessary and why cannot everything be taken out in some Task
? Because the code executed by the window depends on the rendering. I need a person to be able to hide and show the window whenever and as much as necessary, but that his state is the same as if he was not hidden.
Answer:
You can't just fire the Loaded
event: it only fires when your window has actually been shown. But maybe you have a workaround that worked in my project.
First, we'll split the window content into a UserControl
. Let the window be empty. Let's call the SimpleUserControl
for example.
Now, at the beginning of the application, we create a control, but do not show it, thus:
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();
}
}
At the same time, Loaded
on the control is still not called (it will be called only when displayed), but your controls will be in a "working" state.