ShowInTaskbar not working reliably in WPF - c#

I have a modal window in WPF and for this window ShowInTaskbar is set to true but application icon is not showing in taskbar every time for this model window. Sometimes the icon shows up in taskbar and sometimes it does not. But the requirement is application icon should always be visible in the taskbar when this modal window (using ShowDialog) is launched.
window Style is set as : ThreeDBorderWindow
Code to show modal window is :
winIHelper = new WindowInteropHelper(_shell);
_shell.SizeToContent = SizeToContent.WidthAndHeight;
winIHelper.Owner = parentHandle;
_shell.ShowInTaskbar = true;
_shell.Activate();
_shell.ShowDialog();

I had a similar case where ShowInTaskbar was not working correctly when a different window (Splash screen in my case) was shown without setting any Owner.
So, settings the Owner property of the Other window - solved my case.

Related

Wrong (Default?) Icon shown in Taskbar

I have a Form which I show with ShowDialog. I explicitely set the icon for the form with:
using (frmActivation myActivationView = new frmActivation())
{
myActivationView.ShowInTaskbar = true;
myActivationView.Icon = Properties.Resources.icon;
myActivationView.ShowDialog();
}
And I also set it in the project properties in the application tab as mentionend here:
Even though I have set ShowInTaskbar explicitely to true, it will show me the wrong icon.
I'm out of ideas what else could be the reason that it won't show the set icon?
It's not enough to set ShowInTaskbar. You must also make sure that the property ShowIcon of the form is set to true.
Based on the screenshot of your form and the fact, I can't see an icon in the upper left corner, I guess you haven't set it yet.
From the MSDN: Form.ShowIcon Property
The ShowIcon property contains a Boolean value that indicates whether the form's Icon is displayed in the caption bar of the form. If the ControlBox property is false, both the icon and control box will be suppressed.
If ShowIcon is false when the primary form is shown, a generic icon will be displayed in the taskbar button for the application.

WPF modal window as tool window in WinForms disappears

I was wondering if anyone can help me with this rather baffling situation. I have a WPF form myForm which I am displaying modally in a WinForm application (without using an ElementHost). Everything works fine if I use the default WindowStyle and it is shown in the taskbar. However now I don't want the form to show in the taskbar or contain the minimize button, therefore I have done the following:
MyForm myForm = new MyForm();
myForm.ShowInTaskbar = false;
myForm.WindowStyle = System.Windows.WindowStyle.ToolWindow;
myForm.WindowStartupLocation =System.Windows.WindowStartupLocation.CenterOwner;
myForm.ShowDialog();
Now, the wpf form displays as expected modally and without the minimize button. If I now select the "parent" winform application in the taskbar, the wpf form disappears and there doesn't seem to be any way of returning to it! I have read this which is similar but not the same (pure WPF application), so I can understand why the main app does not appear in the ALT+TAB menu, but can anyone tell me how I can return to the wpf form?
Thanks in advance.
The use of WindowsInteropHelper allows you to wrap a hosted WPF-form using a Winforms-form and set its parent as a Winforms control, which prevents the WPF form from disappearing (as also pointed out by dowhilefor and Hans Passant)
E.g.:
// Use the interop helper for the specified wpf window hosted by the win32 owner
WindowInteropHelper wih = new WindowInteropHelper(wpfForm);
wih.Owner = this.someWin32FormsControl.Handle;
This is not related to Winforms or WPF, this is the way Windows functions. The only solution that I think you have is to wire up your modality; that is intercept the Activated event on your Winforms form and if your WPF tool window is visible, bring that window forward and give it focus.

How to simulate a drop-down window in WinForms?

i know a Windows Combobox control is nothing but a Textbox and a ListBoxglued together.
i need to simulate the same thing in WinForms. i am trying to figure out Windows window options that must be set to achieve the proper effect.
the drop-down cannot be a child window - otherwise it is clipped to the parent's area
conceptually it must be a pop-up window - an overlapped window
it can be an owned window - An owned window is always above its owner in the z-order. The system automatically destroys an owned window when its owner is destroyed. An owned window is hidden when its owner is minimized.
The best i've managed so far is to create
a borderless (this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.None)
topmost (this.TopMost = true)
form that doesn't show in the taskbar (this.ShowInTaskbar = false)
this borderless topmost form contains my "drop-down" control. i "hide" my dropdown when the dropdown form loses focus:
this.Deactivate += new EventHandler(TheDropDownForm_Deactivate);
void TheDropDownForm_Deactivate(object sender, EventArgs e)
{
...
this.Close();
}
This conglomeration of mess works well enough...
...except that "drop-down" takes focus away from the owner form.
And this is my question, what properties should my popup window have?
SW_SHOWNOACTIVATE?
But then how do i hide my drop-down form when it loses focus - when it cannot lose focus?
How do i simulate a combo-box drop-down in .NET?
Note: Don't confuse what you see in the example screenshot with something else. i am asking how to create "drop-down" form in Winforms - the contents can be different than the screenshot above:
Using a ToolStripControlHost and a ToolStripDropDown can achieve the same effect.
From this answer:
Private Sub ShowControl(ByVal fromControl As Control, ByVal whichControl As Control)
'\\ whichControl needs MinimumSize set:'
whichControl.MinimumSize = whichControl.Size
Dim toolDrop As New ToolStripDropDown()
Dim toolHost As New ToolStripControlHost(whichControl)
toolHost.Margin = New Padding(0)
toolDrop.Padding = New Padding(0)
toolDrop.Items.Add(toolHost)
toolDrop.Show(Me, New Point(fromControl.Left, fromControl.Bottom))
End Sub

Show hidden window

I'm creating child console application using Process.Start method. Process is created with WindowStyle set to ProcessWindowStyle.Hidden. But then I need to SendInput to this window and try to show it using ShowWindow method. But ShowWindows has no effect.
You need to change also the property of process style form hidden to normal.
The methods Show() set the property is equal to setting the property Visible to true (the Hide() sets it to false).
From the description of ProcessWindowStyle.Hidden:
The hidden window style. A window can
be either visible or hidden. The
system displays a hidden window by not
drawing it. If a window is hidden, it
is effectively disabled. A hidden
window can process messages from the
system or from other windows, but it
cannot process input from the user or
display output. Frequently, an
application may keep a new window
hidden while it customizes the
window's appearance, and then make the
window style Normal.
So in your case, you will have to set the WindowStyle property of Process.StartInfo to ProcessWindowStyle.Normal.

WPF owner window on top of child window

Is it possible for Owner window in WPF be on top of Child window when you click on it while Owner window is below Child window?
here is example how I call child window:
Window2 window = new Window2();
window.Owner = this;
window.Show();
Parent/Owner window will always be under child window.
To get the behavior you want, you don't want to set the Owner on either window.
You, of course will have to handle the logic yourself when closing either of the windows to close your imaginary "child" window.
There may be some other logic you'll have to implement related to minimizing, maximizing, etc.
Many of the answers on this page involve nulling-out the Window.Owner property for some or all of the (non-MainWindow) windows in your System.Windows.Application. While this is a simple and easy fix that does indeed, in isolation, fix the issue of Window overlap, unfortunately it also inhibits a lot of useful application-wide functionality that WPF seems otherwise eager to provide in the areas of:
Application acti­vation/deactivation (via mouse-click, desktop Alt-Tab switching, etc...),
correct observance of the Application.​ShutdownMode property, and generally,
orderly cleanup, resource disposal, and exit of your Application upon shutdown.
It is possible fix the Window overlap issue while still preserving these system-wide WPF features by instead designating a special invisible window instance as your Application.MainWindow.
Modify your application so that the first Window it creates--which is the Window that gets assigned to Application.MainWindow--is a special dummy Window that is then made invisible by setting its Visibility to Visibility.Hidden or calling Window.Hide(). This will not hide its owned windows. Then, ensure that your desired "main" window containing your true content, plus all the other windows, owned by this invisible window.
Once hidden, the dummy Window will not show in the Windows 10 taskbar. You can set the Window.ShowInTaskbar property on whichever of the visible windows you deem appropriate to simulate apparent special designation, as required.
This approach allows any of the visible windows in your Application to be on top of the others, while still preserving WPF features and behaviors for system-wide app activation. For example, when the Application is activated (by clicking on any one of the windows, or via Alt-tab), all of the application's windows are together brought above any other desktop app windows, while still preserving the most recent "in-app" Z-order. WPF shutdown functionality is also preserved, including correct observation of the Application.ShutdownMode logic in accordance with the invisible MainWindow (or all the others) being closed.
I ran into a similar situation. I solved this by simply removing the owner after showing the window.
Window2 window = new Window2();
window.Owner = this;
window.Show();
window.Owner = null;
Edit:
Someone replied to this, and while looking at it, I decided I wanted to make an extension method.
public static void ShowAsIfChildOf(this Window childWindow, Window parentWindow)
{
childWindow.Owner = parentWindow;
childWindow.Show();
childWindow.Owner = null;
}
Please note that the solution mentioned by Licht
Window2 window = new Window2();
window.Owner = this;
window.Show();
window.Owner = null;
seems to me to be the same as
Window2 window = new Window2();
window.Show();
i.e., as if no ownership relationship has been set, i.e., when you close the owner window the owned windows do not close, etc., and may not be a solution when one would wish to have all of the ownership relationship features except "An owner window can never cover an owned window."
Once this relationship is established, the following behaviours are exhibited:
If an owner window is minimized, all its owned windows are minimized as well.
If an owned window is minimized, its owner is not minimized.
If an owner window is maximized, both the owner window and its owned windows are restored.
An owner window can never cover an owned window.
Owned windows that were not opened using ShowDialog are not modal. The user can still interact with the owner window.
If you close an owner window, its owned windows are also closed.
The best solution here looks to me to be the one with hidden main dummy window described by Glenn Slayden, at the link below, though it would be nice if there was a simpler one.
https://stackoverflow.com/a/66110288/19683309
Don't set Owner for child window, then in MainWindow handle OnClosing event like this:
private void MainWindow_OnClosing(object? sender, CancelEventArgs e)
{
foreach (var window in Application.Current.Windows)
{
if (window is Window appWindow)
{
if(appWindow.Equals(Application.Current.MainWindow))
continue;
appWindow.Close();
}
}
}

Categories