I created a C# project which have multiple windows. When I do some other stuff, some of the windows are lost focus. Then I have to bring them to front by clicking the task bar one by one.
I am wondering is there are OnTaskBarClick Event on C# wpf window?
Then What I need to do is to set all sub windows with "ShowInTaskbar="False"". Then when ever my mainwindow is clicked on the task bar, I bring all the windows to the front.
You'll want to use the Window.Activated event to detect when your application's window is brought into focus:
From the documentation:
A window is activated (becomes the foreground window) when:
The window is first opened.
A user switches to a window by selecting it with the mouse, pressing ALT+TAB, or from Task Manager.
A user clicks the window's taskbar button.
Or you could use the Application.Activated event.
Clicking on a control of an already active window can also cause the Window.Activated event to fire, so if the issue is that it's firing too often, you'll probably want to watch for when the application toggles between being active and deactive.
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
Application.Current.Activated += CurrentOnActivated;
Application.Current.Deactivated += CurrentOnDeactivated;
}
private bool isDeactivated = true;
private void CurrentOnDeactivated(object sender, EventArgs eventArgs)
{
isDeactivated = true;
//handle case where another app gets focus
}
private void CurrentOnActivated(object sender, EventArgs eventArgs)
{
if (isDeactivated)
{
//Ok, this app was in the background but now is in the foreground,
isDeactivated = false;
//TODO: bring windows to forefont
MessageBox.Show("activated");
}
}
}
I think what you are experiencing is the window Owner not being set on your child window.
Please refer to Window.Owner Property
When a child window is opened by a parent window by calling
ShowDialog, an implicit relationship is established between both
parent and child window. This relationship enforces certain behaviors,
including with respect to minimizing, maximizing, and restoring.
-
When a child window is created by a parent window by calling Show,
however, the child window does not have a relationship with the parent
window. This means that:
The child window does not have a reference to the parent window.
The behavior of the child window is not dependent on the behavior of the parent window; either window can cover the other, or be
minimized, maximized, and restored independently of the other.
You can easily fix this by setting the Owner property in the child window when before calling Show() or ShowDialog()
Window ownedWindow = new Window();
ownedWindow.Owner = this; // this being the main or parent window
ownedWindow.Show();
Note : if conforming to an MVVM pattern, this can become a little
more cumbersome, however there is plenty of resources on how to link owner and parent windows.
Related
i'm using a listview to display multiple items to the user. Now I want that the user has the ability to open an detail window with an double click. This works fine but when the window is opened it's immediatly pushed to the background.
I tried several things with the window state etc. the result was in every situation terrible(window is pushed to background or the window is a permanent overlay). The only solution that works relative well is that I change the DoubleClick Event in a MouseLeftButtonUp Event. When a user now click an item the window are in the foreground.
This is my code from the controller class:
public void ShowDetails(object details)
{
Details detailWindow = new Details(this, Config.GetCultureInformation());
detailWindow.LoadData(details);
detailWindow.Show();
}
This my code from the UI Class
private void listViewItem_MouseClick(object sender, MouseButtonEventArgs e)
{
ListViewItem item = sender as ListViewItem;
AppControl.ShowDetails(item.Content);
}
You should show it as modal.
public void ShowDetails(object details)
{
Details detailWindow = new Details(this, Config.GetCultureInformation());
detailWindow.LoadData(details);
detailWindow.ShowDialog(); //Instead of detailWindow.Show();
}
If you want to keep your main window without freeze use detailWindow.BringToFront() or detailWindow.TopMost = true, take a loot at this other post
Source here.
Ok. Thank you for your help and with Topmost I find I way to create a solution that suits for me.
In the constructor of my window I set topmost to true and in the Window is Loaded Event I set topmost to false. My Window is prominent in the foreground but the user can go out of it and can handle things in the main app.
I have a C# Windows Forms application which has a main form that opens two other forms in it's constructor. I'll call them side-panels.
The main form has the GotFocus event handled, which calls Form.BringToFront() for both the side-panel forms.
When this functionality is enabled(i.e. GotFocus is handled), the close button for the main form stops working.
How can I check if the close button was pressed in the event handler?
public Canvas()
{
InitializeComponent();
this.GotFocus += new EventHandler(WindowGotFocus);
tool.Show();
pp.Show();
}
public void WindowGotFocus(object sender, EventArgs e)
{
tool.BringToFront();
pp.BringToFront();
}
When I press the close button the main form, it gets focus, the WindowGotFocus method is called, and application does not close. If I comment 'this.GotFocus += new EventHandler(WindowGotFocus);' in the constructor, it works.
I need this functionality so that the side-panels are shown again if the use switches back to the application from another application.
Well, of course it doesn't work. You caused the form to lose focus, which means that the click never happened as far as the window is concerned.
The proper way to handle this is by simply making the tool windows children of the main window:
var parent = new Form();
var child = new Form();
parent.AddOwnedForm(child);
parent.Show();
child.Show();
This will automatically handle the behaviour you expect - after all, you expect that behaviour because other applications do the exact same thing :) Apart from making sure the child windows show when the main window does, it also closes all child windows when the parent window is closed, among other things.
Is it possible to make that when child window is opened, parent window is minimized and is inactive (child window is modal)?
I tried changing WindowState property to minimized for parent window before calling child window, but then child window starts minimized.
Not sure why you want to do it this way, but this is doable with some trickery (or good design patterns). With trickery you can do this:
From parent (form1):
private void button1_Click(object sender, EventArgs e)
{
this.WindowState = FormWindowState.Minimized;
this.ShowInTaskbar = false;
new Form2().ShowDialog(this);
this.WindowState = FormWindowState.Normal;
this.ShowInTaskbar = true;
}
Although, I would recommend reconsidering your architecture instead.
There is a flaw in your design.
You have two top-level Windows, the main form and the child modal dialog. The child modal dialog is what is known as, in Win32 terminology, an owned window. The main form is un-owned. When a top-level un-owned Window is minimized, all the windows that it owns are hidden. That is functionality provided by the desktop window manager.
The documentation states:
An owned window is hidden when its
owner is minimized.
What you are trying to do sounds unusual anyway. Normally when a form shows a modal dialog, the modal dialog is shown on top of the other form. Why are you wanting to hide the main form?
If you are dead-set on this design you need to arrange that your modal dialog is an un-owned window. When you do so it will appear as an item in the taskbar separate from your main form. Is this what you want?
In the child form_Load event, try this :
frmParent frm = new frmParent();
frm.WindowState = FormWindowState.Minimized;
I have a parent window which launches a child window, after doing some selection/operation in the child window is closed and I want to send some info back to the parent window (a custom class object), what's the best way to accomplish this in WPF using the features provided by WPF?
You have many options:
You could use a custom event in your child window that the parent window listens to
You could define a delegate in the child window that references a method in the parent window
You could change the constructor for the child window to take a reference to the parent window and call a method on the parent window using that reference
You could possibly use the VisualTreeHelper class to get the parent window and call a method on that reference
Extracted from this link:
The easiest way I have found to pass data from a child window to a
parent window is to use an application wide property. This property is
an object, and is not the most elegant form to pass data from a child
window to a parent, but it's the least amount of programming. The best
way to do this is using get and set accessor properties.
Create a main window (mainWindow) Create a child window (in this case,
Password)
In the main window, the child window must be shown, say, within a
button click. This window would have a button to do something, in this
case, it's to delete a record from the database.
private void btnDelete_Click(object sender, RoutedEventArgs e)
{
Password passwordentry = new Password();
passwordentry.ShowDialog();
if (Application.Current.Properties["PassGate"].ToString() == "mypassword")
{
Code, or call to delete the record;
}
Application.Current.Properties["PassGate"] = "";
}
In the child window (Password), the property for the application is
set using a textbox. This is a simple window that has a textbox called
PasswordTextBox and a couple of buttons, like Accept and Cancel.
private void AcceptButton_Click(object sender, RoutedEventArgs e)
{
Application.Current.Properties["PassGate"] = PasswordTextBox.Text;
this.Close();
}
I have a dialog-based application.
I need to show a child window like this:
(1) First, the application's main dialog window will show up,
(2) then, a child dialog window will show up automatically on top of that.
You know, it is not enough to call the child window's ShowDialog() in the parent window's constructor or load event. Coz in those cases, the child window will appear first.
What should I do to achieve that?
Use can use the event Shown of your main dialog, to show the child in front of you main dialog. This event is only raised once, when the main dialog is shown the first time. Also you should use the Show() (not ShowDialog) method and then call BringToFront() of your child dialog.
private void OnShown(EventArgs e) {
ChildDialog child = new ChildDialog();
child.Show(this);
child.BringToFront();
}