Application.Current.Activated doesn't fire while .ShowDialog() active - wpf

I am using Application.Current.Activated to bring all windows to the front when any one is clicked. This is working great, but doesn't work when I have a modal dialog open using .ShowDialog()
Clicks on other windows of the application (besides the dialog) do not result in the application being activated. The default behavior is to do nothing. (The clicks appear to be entirely IGNORED!)
How can I make it so that when any window of the application is clicked, the open dialog is brought to the front? (The expected behavior based on how pretty much every application works)
YES: I did set the owner of the dialog to my MainWindow, and clicking on the main window produces the desired result, but clicking any other window does nothing.
Code:
Create a new WPF project and add two windows.
Then put a button on MainWindow.
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
Window1 foo = new Window1();
foo.Show();
}
private void Button_Click(object sender, RoutedEventArgs e)
{
Window2 modal = new Window2();
modal.Owner = this;
modal.ShowDialog();
}
}
To see what I'm talking about, click the button to open the modal dialog.
The desired behavior is what happens when MainWindow is clicked.
I want the same to happen when Window1 is clicked.

AFAIK, a modal dialog (which .ShowDialog() triggers) blocks all other windows thereby Activation events.
As per the MSDN:
When a Window class is instantiated, it is not visible by default. ShowDialog shows the window, disables all other windows in the application, and returns only when the window is closed. This type of window is known as a modal window.
http://msdn.microsoft.com/en-us/library/system.windows.window.showdialog(v=vs.110).aspx
This may be an ugly hack, but maybe you can accomplish what you need to by creating your modal window on a separate thread thereby letting your main application continue to process activation (and other) events? You would need a way to prevent 2 of that 2nd modal dialog from opening though.

Related

Wpf app in VS2017

I'm adding manually a click event in main window of mainwindow.xaml. There are no faults in xaml editor and the button is visible.
When switching back to the mainwindow.xaml.cs my click event is NOT automatically added. It goes for all events. These events should be automatically added in the .cs editor along the lines of:
private void Button_Click(object sender, RoutedEventsArg e)
{
}
Any ideas, pointers?
If by "adding manually an click event" you mean manually typing in the XAML in the editor then no it does not add it for you at that point.
If IntelliSense is working for you, as you type in the Click="" text, it should popup a menu listing the already available click handlers that you can select AND at the top of that list should be a choice labelled "<New Event Handler>". If you select "<New Event Handler>" it will add it in for you at that time.
If you don't choose anything from the list but instead just type it in, it is not added. However, at that point, at least for Button controls, you can double-click the button control in the XAML Designer and it will add the click handler into the .xaml.cs code and take you to it.

Winforms TextBox gets focus but doesn't capture keyboard input

This has me baffled.
I've written a popup box which consists of a WinForms UserControl hosted inside a WindowsFormsHost, which, in turn, is hosted in a Primitives.Popup which is displayed on the screen. The whole application is WPF, but this control was lifted from an earlier application written in WinForms.
The popup is activated by an external event (an incoming phone call from a CTI Server).
Inside the UserControl is a textbox control. When the user clicks in the text box, I call the Focus method on the Popup, then call the Focus method on the textbox. The textbox gets the focus. I can be fairly sure of that because the box shows a cursor after clicking in it, and also I have a "GotFocus" event handler that prints a debugging message.
However, if there was another program active at the time the incoming event occurs, any keys that are pressed on the keyboard continue to go to that program, not to the text box. Only if the user clicks in another part of my application (i.e., part of the screen outside the popup) to make it the active program, and then clicks in the text box is the text box able to receive keyboard input.
I hope I've given enough information without overwhelming you with the myriad of details. If there's something else anyone needs to point me in the right direction, I'll be happy to provide it.
Because the WinForm TextBox is hosted, setting focus on it does not activate the hosting WPF Window. Add a line to activate the Window.
private void TextBox_Click(object sender, EventArgs e)
{
this.Activate(); //activate the Window
(sender as System.Windows.Forms.TextBox).Focus();
}

Setting focus on WPF ComboBox not always working

I have a solution, that has two projects, the main one and a small shared control that's used as well. In our application, a certain feature opens this shared control in a new window. I want to set the focus to the first combobox in this control when the window opens.
In my code, on the window that loads the shared control, at the end of the _Loaded event, I set focus to this combobox. But when running the code - I still have to hit tab to have 'keyboard' focus on the box (as in, I would have to hit tab to then start typing the name of one of the items in the list).
If I set a breakpoint here, hit it, and then continue - it actually is set the way it should be. If I use a WPF inspector - IsFocused is also set.
Other things noticed:
If I hit tab (to get what I want), then tab back, it takes me to the last control on the form, not to this unknown control. This makes me believe the focus is set right, but for some reason doesn't have correct keyboard focus.
If I try to use MoveNext in code, it actually selects the next item in the window, outside of the control.
How do I properly set focus here? On another combobox in the 'main' project, just calling .Focus() worked correctly.
try to postpone the focus() after all events are handled and bindings updated with QueueUserWorkItem. Something like this :
public delegate void VoidDelegate();
private void Window_Loaded(object sender, RoutedEventArgs e)
{
// Some other things to do here.
System.Threading.ThreadPool.QueueUserWorkItem
(x => this.Dispatcher.Invoke(
new VoidDelegate(SetFocus), null));
}
private void SetFocus()
{
MyControlIWantToSetFocusOn.Focus();
}

Closing a Window in WPF (When not in that Window)

I have an application which starts with a simple start screen allowing the user to select either New or Open a project. When selecting New I have a new window displayed which is a wizard that collects data to be passed to the Main window.
I create a new Window for the Main window and show that.
Then I close the wizard easily enough with this.close();
But how do I close the initial window which is the Startup URI window?
Application.Current.MainWindow.Close();
Pass the Startup window to the main window as a constructor parameter or property, then call Close() on it.

Is there a way to re-use an already closed WPF Window instance

I have a Window instance which I show by calling wInstance.ShowDialog() from a button click and I close the window by pressing Alt+F4. The issue now is that I cant call wInstance.ShowDialog() again. How can I re-use the same window instance again.
Exception :
Cannot set Visibility or call Show or ShowDialog after window has closed.
You need to override the wInstance OnClosing method to set the window visibility to hidden and cancel the close event.
protected override void OnClosing(System.ComponentModel.CancelEventArgs e)
{
this.Visibility = Visibility.Hidden;
e.Cancel = true;
}
What exactly is it that makes it so important to use the same window?
If you are using MVVM, you could just reuse the viewmodel for a new window.
I'm reusing a window as a Dialog that uses a treeview and the client wants the tree branches to remain open for a more selections.
The override worked for re-use, and the branches stay expanded.
I'm not using a view model to keep it simple as it is a read only selection dialog. But since I can't seem to clear the selection yet, I may have to switch to a view model.

Resources