WPF application login window not on top - wpf

I'm using Prism's MefBootstrapper to initialize my WPF application, as part of this process the Shell window is being initialized.
After Running the MefBootstrapper's Run() method, I'm displaying a login window which connects to a server and in case of a successful connection, the Shell is loaded (from main UI thread).
This login window is running on a new dedicated UI thread, in order not to freeze the progress-bar in this process (connection to the server and especially the Shell loading).
Unfortunately, the login window is not showed on the top and not Focused (even when I'm using: Activate(), TopMost=true, Focus() ).
//UI mode - a new UI thread is initialized
var uiThread = new Thread(() =>
{
var loginWindow = new LoginWindow();
loginWindow.Show();
loginWindow.Activate();
loginWindow.Topmost = true;
loginWindow.Topmost = false;
loginWindow.Focus();
System.Windows.Threading.Dispatcher.Run();
});
uiThread.SetApartmentState(ApartmentState.STA);
uiThread.IsBackground = true;
uiThread.Start();
How can I solve this issue?

Try uiThread.IsBackground = false;
Can you send new instance of LoginWindow to the thread?
uiThread.Start(new LoginWindow());
and then use the loginWindow parameter in the Thread delegate to Show.
I guess that would cause the window to render in the current dispatcher context and would render it on the foreground.

I would create the loginWindow before the ShellWindow is created, just before the end of ConfigureContainer().
That way you won't unnecessarily create views - viewmodels in your regions.
Note, it is important that you don't Close the window before you have shown your ShellWindow (i.e. hide it on successful login) or else the Application will close too.

Related

Dispatcher.BeginInvoke is not triggering in WPF

I am new to WPF and i am trying to create a WPF form and trying to call from another application . I am converting the WPF output as class libarary and calling from another Solution .
There is a .cs file which call this wpf window from code behind using below code .
Thread thre = new thread(()=>
{
mainwindow md = new mainwindow();
md.ShowDialog();
md.Closed+=(s,e)=> md.dispatcher.InvokeShutdown();
Dispatcher.Run()
});
thre.SetApartmentState(ApartmentState.STA);
thre.Start();
I Can able to call my window and all my functionality working excel the dispachter.beginInvoke is not triggering .And i also get Application.Current =null . I am unable to go to if statement in the below code.
Method in window.cs
new Thread(()=>
{
rsult= getItemID("44");
Dispatcher.BeginInvoke( new ThreadStart(()=>{
if(rsult==0)
{}
});
}).Start();
}
ShowDialog() blocks. You should register your event handler, show the window by calling the Show() method and then start the message pump by calling Run():
Thread thre = new thread(()=>
{
mainwindow md = new mainwindow();
md.Closed += (s,e) => md.dispatcher.InvokeShutdown();
md.Show();
Dispatcher.Run()
});
thre.SetApartmentState(ApartmentState.STA);
thre.Start();

Application closes if any window is shown before the main window

I have a very puzzling case. During the initialization of my application, before any windows are shown, this function deserializes application settings from XML file, but if deserialization function throws any errors, it displays an error message to the user (which is a custom-made WPF dialog), and once that message dialog is closed, it creates new instance of the settings, and continues the initialization:
Public Function LoadSettings()
Try
Return DeserializeFromXML(settingsPath)
Catch ex As Exception
Msg.ShowMessage(Msg.corruptedSettingsFile)
Return new AppSettings
End Try
End Function
ShowMessage is defined as:
Public Function ShowMessage(message As Message) As Boolean
Dim messageDialog As New MessageDialog(message.Title, message.Content, message.Buttons)
Return messageDialog.ShowDialog()
End Function
Now, the weird thing is, after that exception is caught, and error message is closed by the user, initialization continues, but when it arrives at mainWindow.Show(), nothing happens. Main window is not shown. And once initialization code finishes, the application closes immediately.
In my Application Properties, the Shutdown mode is set to "On main window close". StartupUri is not set, because I want to show that main window exactly when I want, not automatically. However, for testing, I tried to remove mainWindow.Show() altogether, and set StartupUri to MainWindow.XML, but it doesn't solve the issue either.
I have tested that if I do not display that error message to the user, the application loads correctly, either with mainWindow.Show() or with StartupUri.
Why is this happening?
EDIT: I forgot to mention, which is probably important, that before the mainWindow.Show(), I also call Application.Current.MainWindow = mainWindow. So in case WPF makes that message dialog main window, this call should override it... But it still doesn't work.
EDIT 2: I discovered that if I call Application.Current.ShutdownMode = ShutdownMode.OnExplicitShutdown before showing the message, and restore it with Application.Current.ShutdownMode = ShutdownMode.OnMainWindowClose and also call Application.Current.MainWindow = mainWindow, then the application does not close, and all works correctly. However, this is a horrible solution. It is obvious now that the message dialog hijacks the Application.Current.MainWindow. How do I stop this behavior on the application level, so that the Application.Current.MainWindow would only get set when I explicitly set it?
you must set MainWindow before calling ShowDialog methed of any other windows. The reason of this is: a window that was created in application thread, will set itself as main window if MainWindow was null; and after ShowDialog was called, you would have any chance to fix this because of modal mode.
// this will work.
private void Application_Startup(object sender, StartupEventArgs e)
{
var a = new MainWindow();
var b = new MessageDialog();
b.ShowDialog();
a.Show();
}
// this will not.
private void Application_Startup(object sender, StartupEventArgs e)
{
var b = new MessageDialog();
b.ShowDialog(); //app shutdown at this point
var a = new MainWindow();
a.Show();
}

Multiplethreading MVVM update value when Current Dispatcher is working

I've problem with update value in window, which is open via Show() method not ShowDialog() method. I use MVVM and use binding like:
Value="{Binding Path=MainProgressValue, UpdateSourceTrigger=PropertyChanged}"
In my property I use INotifyPropertyChanged for notify UI.
It worked fine, but now I open new window
window.DataContext = context;
if (owner != null)
window.Owner = owner;
resultHandler = new ViewModelBaseClass.ResultHandler(context_RequestClosing);
getDialogResultHandler = new ViewModelBaseClass.GetDialogResultHandler(context_GetDialogResultAction);
context.RequestClosing += resultHandler;
context.GetDialogResult += getDialogResultHandler;
window.Show();
There is progress bar. The window is shown and main thread continue with proceed program. But when DataContext call RaisePropertyChanged, the progress bar doesn't update. Is it possible that the window with progress bar uses another thread than the main thread?
How to update this value?
My guess based on your description is that you are expecting the UI to refresh while the main application thread is busy doing something. The main application thread is the UI thread so if this is the case you UI thread is blocked.
What you need to do is move the "program" portion that is doing the loading etc. and updating the progress value off into a worker thread (See ThreadPool) and when you want to signal the UI to refresh use the Dispatcher.BeginInvolke() example you found. This will execute your refresh code on the main UI thread.

Make child window always on top of all windows

I'm writing in wpf. In my viewModel I have a command that opens new window. However sometimes this child window is placed under the parent window. (if for instance I work in my application, then open browser and want to return to my application). Window is opened as follows:
MyViewModel vm = new MyViewModel(oper);
Mywindow window = new MyWindow();
//Initialize viewModel and set window.DataContext to this viewModel
CWPFWindowWithViewModelHelper<IWindowWithViewModel>.InitializeViewModel(window, vm);
window.ShowDialog();
I want this child window to be always visible when opened. How can I do this?
just try with
window.Owner=this
window.TopMost = true;

WPF application is not closing correctly

I am calling Application.Current.Shutdown() from a class that is bound to xaml windows with ObjectDataProvider, but the application is not closing. Can anyone help me to understand why? My application is not closing completely after my main window is closed, it doesn't disappear from task manager's process list.
Try Environment.Exit(0) instead
Have you created any threads to do background processing? If you have, make sure to set the .IsBackground property on them, or they can keep the app running
Don't forget to add this:
private void Window_Closed(object sender, EventArgs e)
{
Application.Current.Shutdown();
}
Hope this helps.
If you have multiple windows or dialogs in your application, you may need to close each one explicitly.
Close dialogs with:
_myDialog.Close();
Close all windows:
foreach(var window in Application.Current.Windows.ToList())
{
window.Close();
}
I had a problem where the application would not shut down even when main window was closed. It turned out I had done Hide() on the splash screen instead of Close() so it was still lurking in the background keeping the application alive.
I had the same problem, the application process doesn't stop although the application closed.
In my case I opened a window from a BackgroundWorker (code below)
BackgroundWorker BG = new BackgroundWorker();
BG.DoWork += new DoWorkEventHandler(BG_DoWork);
StockMinWindow MinWindow = new StockMinWindow(null); -------- this is the problem
BG.RunWorkerAsync();
instanciate the window before running the BackgroundWorker seem not being the problem but by erasing the line the application closed correctly
I open my window from the BackgroundWorker but using the principal Thread (code below)
View.Dispatcher.BeginInvoke(new Action(delegate()
{
StockMinWindow MinWindow = new StockMinWindow(StockMinList);
MinWindow.Owner = View;
MinWindow.ShowDialog();
}));
Hope it helps.

Resources