Second Window Positioning WPF - wpf

I have MainWindow which has a button that allows it to open another WPF Window. I want this window to open always on the right hand side of the MainWindow practically right next to it.
How can I do this? This needs to work even if the width of the MainWindow changes as I have various buttons on the MainWindow that can change the size of the MainWindow depending on what panel is visible.

You can calculate where you want the new window if you have a reference to the other window.
Get the other windows position by accessing the Left and Top properties and its width by accessing the ActualWidth or the Width property.
Now you can calculate the new windows position by adding Left + Width + Some spacing.
Check out the documentation for the Left property here:
http://msdn.microsoft.com/en-us/library/system.windows.window.left.aspx
The others behave similarily.

You need to set manual startup location for second window in properties or in code:
WindowStartupLocation = WindowStartupLocation.Manual;
On events Loaded, SizeChanged, LocationChanged of first window, you should adjust position of second window like this:
public void AdjustPosition()
{
window2.Left = Application.Current.MainWindow.Left + Application.Current.MainWindow.ActualWidth;
window2.Top = Application.Current.MainWindow.Top;
}
private void MainWindow_Loaded(object sender, RoutedEventArgs e)
{
AdjustPosition();
}
private void MainWindow_SizeChanged(object sender, SizeChangedEventArgs e)
{
AdjustPosition();
}
void MainWindow_LocationChanged(object sender, EventArgs e)
{
AdjustPosition();
}

Related

(WPF) Does .Close() method releases the window instance?

I'm creating a new window in On_Click method. First I tried this;
public partial class MainWindow : Window
{
CustomerOperations customerOperationsWindow;
public MainWindow()
{
customerOperationsWindow = new CustomerOperations();
InitializeComponent();
}
private void btnCustomer_Click(object sender, RoutedEventArgs e)
{
customerOperationsWindow.Owner = this;
customerOperationsWindow.Show();
}
}
It's not working so I started creating the window instance every time the user clicks on the Customers button. And I used the following codes.
private void btnCustomer_Click(object sender, RoutedEventArgs e)
{
CustomerOperations customerOperationsWindow = new CustomerOperations();
customerOperationsWindow.Owner = this;
customerOperationsWindow.Show();
}
In the new window, If user clicks to Main button, I want to navigate to main window.
private void btnMain_Click(object sender, RoutedEventArgs e)
{
this.Close();
this.Owner.Show();
}
First question: Does this.Close() releases the window instance?
Second question: Is this usage correct?
What do you think is the best practice?
Thank you all.
Window.Close() will dispose all resources allocated by the instance. That's why you cannot show it again once it was closed.
If you want to reuse the same Window instance, you should cancel the closing procedure to prevent disposal of internal resources and collapse the Window instead (by setting Window.Visibility to Visibility.Collapsed - Visibility.Collapsed is also the default value of an instantiated Window before Window.Show() is called).
Alternatively hide the Window by calling Window.Hide() (which will set the Visibility to Visibility.Hidden) instead of Window.Close().
Calling Window.Show will also set the window's visibility to Visibility.Visible.
As a matter of fact, showing a Window by setting Window.Visibility is the asynchronous version of Window.Show().
Generally, you switch between Window instances by using the Window.Activate method. Calling Window.Show on a Window that is currently showing/visible, does nothing.
public partial class MainWindow : Window
{
CustomerOperations CustomerOperationsWindow { get; }
public MainWindow()
{
InitializeComponent();
this.CustomerOperationsWindow = new CustomerOperations();
// Consider to move this logic to CustomerOperations class,
// where you can override the OnClosing method instead of subscribing to the event
this.CustomerOperationsWindow.Closing += CollapseWindow_OnClosing;
}
// Cancel close to prevent disposal and collapse Window instead
private void CollapseWindow_OnClosing(object sender, CancelEventArgs e)
{
e.Cancel = true;
this.CustomerOperationsWindow.Visibility = Visibility.Collapsed;
this.CustomerOperationsWindow.Owner.Activate();
}
private void btnCustomer_Click(object sender, RoutedEventArgs e)
{
this.CustomerOperationsWindow.Owner = this;
// Calling Show will set the Visibility to Visibility.Visible
this.CustomerOperationsWindow.Show();
}
}
Creating a Window instance allocates unmanaged resources. If this happens very frequently, you will keep the garbage collector busy. From a performance point of view you may want to avoid it and prefer to reuse the same instance.
In a common scenario this is not necessary. But since Window exposes a Hide() method, you may consider to use it instead of Close().
If you want to switch to the parent window, you can use the code this.Owner.Activate(); and if you want to close the current window, first this.Owner.Activate(); and then this.Close();.
When you enter this.Close(), the compiler does not execute the following lines after reaching it. And when a sample window still exists there is no need to recreate it
private void btnMain_Click(object sender, RoutedEventArgs e)
{
this.Owner.Activate();
this.Close();
}

How to detect taskbar position WPF

I've created an app in C# / WPF with NoStyleBorder.
When I maximize my app all screen is recover by this, I use systemparameters values area for fix it.
But, If user change taskbar position like Bottom to Left, my app doesn't change position.
How to detect this changing position of the taskbar ?
Set
WindowState="Maximized"
in XAML and in the Loaded-Event of the Window call
private void MainWindow_OnLoaded(object sender, RoutedEventArgs e)
{
this.WindowStyle = WindowStyle.None;
}

Wpf not all windows are maximized from taskbar

I have three windows. FirstWindow, SecondWindow and ThirdWindow. FirstWindow has button and click on this button opens the SecondWindow. Analogously, SecondWindow has button and click on this button opens the ThirdWindow. Owner property of the SecondWindow is set as FirstWindow and Owner property of the ThirdWindow is set as SecondWindow. The scenario discribing problem:
Open all windows in a row. It will be looked like this:
Then minimize all windows by click on corresponding icon at top right corner of ThirdWindow.
If you will try to maximize all windows by clicking on FirstLevelWindow or ThirdLevelWinow in taskbar - all will be ok, three windows will be maximized. But if you will click on SecondWindow you will see this:
How can I fix it, or it is just WPF bug? I can give archived expample project if it helps.
UPDATE
Minimize window - click "_" icon, left icon in iconbar of the window. All windows are modal, i.e it opens with ShowDialog() method, not with Show() method. So if you minimize third window - all the windows will be minimized.
Here the code if you don't want download project by link:
FirstWindow XAML:
<Button Click="OpenChildWindow"
Content="ChildWindow"/>
FirstWindow .cs:
private void OpenChildWindow(Object sender, RoutedEventArgs e)
{
var window = new SecondLevelWindow();
window.Owner = this;
window.ShowDialog();
}
SecondWindow XAML:
<Button Click="OpenChildWindow"
Content="ChildWindow"/>
SecondWindow .cs:
private void OpenChildWindow(Object sender, RoutedEventArgs e)
{
var window = new ThirdLevelWindow();
window.Owner = this;
window.ShowDialog();
}
ThirdWindow is empty window without any content.
Here link to example project
I've just found, that bug is not reproduced if property ResizeMode of ThirdWindow is set to "NoResize". Mb it will be usefull information.
Well, I admit I have no idea what is going on. Did you try to add a fourth window? This become even stranger: the second window bring back the third, but the fourth is still not back.
Anyway, If I had to manage this problem, I would keep a reference of my childWindow in each parent Window. This way on any interesting event (like activate on the second window in your example) I could manage the state of my child as required (WindowState.Normal in your case).
It could be something like that: in xaml of secondWindow:
Activated="SecondLevelWindow_OnActivated"
And then in code behind:
private ThirdLevelWindow _window;
public SecondLevelWindow()
{
InitializeComponent();
}
private void OpenChildWindow(Object sender, RoutedEventArgs e)
{
_window = new ThirdLevelWindow ();
_window.Owner = this;
_window.ShowDialog();
}
public void SecondLevelWindow_OnActivated(object sender, EventArgs e)
{
if (_window != null)
{
_window.WindowState = WindowState.Normal;
}
}
This is a start, but you could also inspect your current state to define the state of your child.
Hope it helps.

WPF path shape title

I have a path shape, i want to set a label above the path ,i put a textblock above the path then i handle the Path_MouseEnter , Path_MouseLeave and change the path background the problem is when the mouse leave the path shape to textblock the background changed the other problem when i handle the Path_MouseDown , the textblock also make a problem is there a beter way to set a label above the path shape ?
private void Path_MouseEnter(object sender, MouseEventArgs e)
{
(sender as Path).Fill = System.Windows.Media.Brushes.Yellow;
}
private void Path_MouseLeave(object sender, MouseEventArgs e)
{
(sender as Path).Fill = System.Windows.Media.Brushes.LightGray;
}
private void Path_MouseDown(object sender, MouseButtonEventArgs e)
{
}
Your question is difficult to follow, but I think you mean that you have a TextBlock overlayed on top of a Path, and when the mouse hits the textblock, your Path_MouseLeave() is triggered but your don't want it to be?
If this is the case, just set IsHitTestVisible="False" on the TextBlock to make it transparent to mouse events.

WPF - Toggle Visibility of multiple windows

i will first explain the UI of my WPF App.
I have created a window which contains many buttons which is always visible to the user(lets call it main window), each button will open a new window relevant to the task. what i want done is that whenever a button is clicked, the main window should be hidden(visibility : collapsed) and the new window should be shown. This second window will also contain a button which will hide the second window and show back the main window.
also the second window which will be opening will have different dimensions as per the command associated with it so i will be having different windows for eaach
TLDR i want to be able to switch between multiple windows such that only one window is visible at one time, how do i manage the switching between multiple windows ??
Note : I can show the second window from main window but what about showing main from the second window....can't get it....or if anyone can show me a different approach to implement this : other than multiple windows
Also, this is an extension to the UI, i want to show the buttons in this crystalised sort of look like on this page : http://postimage.org/image/4yibiulsh/
can anyone direct me to a proper implementation, i have been through many sites and also tried to create these through blend but i just am not a UI Person....pls need help on this
Thanks in advance.
I would create a "Window manager" which will subscribe to the changes of opening/closing.
In this case you don't have to overload Window classes.
Example (worked for me).
public class WindowsManager
{
static readonly List<Window> Windows=new List<Window>();
public static T CreateWindow<T>(T window) where T:Window
{
Windows.Add(window);
window.Closed += WindowClosed;
window.IsVisibleChanged += WindowIsVisibleChanged;
return window;
}
static void WindowIsVisibleChanged(object sender, DependencyPropertyChangedEventArgs e)
{
var mainWindow = Application.Current.Windows.OfType<MainWindow>().Single();
mainWindow.Visibility = Equals(e.NewValue, true) ? Visibility.Hidden : Visibility.Visible;
}
static void WindowClosed(object sender, System.EventArgs e)
{
var window = (Window) sender;
window.Closed -= WindowClosed;
window.IsVisibleChanged -= WindowIsVisibleChanged;
Windows.Remove(window);
}
}
How to use:
private void button1_Click(object sender, RoutedEventArgs e)
{
WindowsManager.CreateWindow(new Child1()).Show();
}
private void button2_Click(object sender, RoutedEventArgs e)
{
WindowsManager.CreateWindow(new Child2()).Show();
}
So, when the child window will close, WindowsManager will be notified about this and will update visibility for the main window
UPD1.
added line to unscubscribe from VisibleChanged
You can use several approaches for that.
To easy switch back to main Window: inject a reference of your MainWindow to your SecondWindow (or any other Window you want to display) and in the Closing Event of that Window you set the Visibility of the MainWindow back to Visible.
Have you also considered keeping everything in the same Window but having different Panels that you set Visible and Invisible? That could have the same effect but it's less complicated...
Hope that helps...

Resources