WPF window position - c#

I have asked a question before about creating a child window here ... Now when I open child window, it doesn`t open centered to the parent window. How can I set it to open centered to the parent window?

This solution worked fine for me.
Here’s a method I’ve found for centering a window to either its parent or the main window for the application, in WPF. It’s not too different from how you do it in WinForms.
For the child window, set its WindowStartupLocation to “CenterOwner”. This will cause it to show in the center of the owning Window.
Collapse
<Window x:Class="WpfApplication1.TestChild"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="TestChild" Height="300" Width="300"
WindowStartupLocation="CenterOwner">
Now, all that’s left to do is set its owner before displaying it. If the code you’re using to display the window is running inside of a Window class, then you can just use this.
Collapse
TestChild testWindow = new TestChild();
testWindow.Owner = this;
testWindow.Show();
This isn’t always the case, however; sometimes, you need to display the child window from the code running on a page or a user control. In this case, you want the child window to be centered to the main window of the application.
Collapse
TestChild testWindow = new TestChild();
testWindow.Owner = Application.Current.MainWindow;
testWindow.Show();

Try this.
aboutWindow.WindowStartupLocation= WindowStartupLocation.CenterOwner ;
aboutWindow.ShowDialog(this);

You can try this:
AboutWindow window = new AboutWindow();
window.WindowStartupLocation = System.Windows.WindowStartupLocation.CenterOwner;
window.Owner = this;
window.ShowDialog();

Related

Open Window on the Same Monitor as MainWindow

I've seen many questions regarding similar issues, but I haven't found one quite specific enough to my question to find an answer yet.
I allow the user to move the MainWindow of my program around and, if they have one, onto another monitor. When they click to add something on the MainWindow, a new Window is created so they can fill in a form.
The problem is that this new Window will start on the primary screen of the OS instead of starting on the screen that the MainWindow is currently located on.
I had a look at this question; How to make a dialog(view) open up on the same monitor as the main window and saw that setting the owner to the MainWindow worked in this case. So I added
Owner = Application.Current.MainWindow;
into the Window_Loaded method the new Window. This does load the Window on the same screen as the MainWindow but then crashes, stating Cannot set Owner property after Dialog is shown.
Naturally I move the setting of the Owner property to before the new Window is shown, so it looks like this;
contractAddwindow.Owner = Application.Current.MainWindow;
contractAddwindow.ShowDialog();
however this then has the same issue as before, the contractAddWindow starts on the primary screen.
So my question is, how do I force the new Window to load on the same monitor as the MainWindow instead of the primary screen?
You can use WindowStartupLocation:
From XAML:
WindowStartupLocation="CenterOwner"
From Code:
WindowStartupLocation = WindowStartupLocation.CenterOwner;
#EDIT: Consider trying Nawed's answer (see below) before using this one. His is much simpler.
Try this methods:
using System.Windows;
using System.Windows.Forms; // Reference System.Drawing
[...]
public void SetWindowScreen(Window window, Screen screen)
{
if (screen != null)
{
if (!window.IsLoaded)
{
window.WindowStartupLocation = WindowStartupLocation.Manual;
}
var workingArea = screen.WorkingArea;
window.Left = workingArea.Left;
window.Top = workingArea.Top;
}
}
public Screen GetWindowScreen(Window window)
{
return Screen.FromHandle(new System.Windows.Interop.WindowInteropHelper(window).Handle);
}
And then, call it like this from the constructor of the Window you want to show on the same monitor as the MainWindow:
SetWindowScreen(this, GetWindowScreen(App.Current.MainWindow));

Re-sizing popup window in WPF from ViewModel

A bit of a complex one. I'm using WPF MVVM and I need to display results in a grid, then when you double click on one it loads that result in a separate popup window.
To do this, I have created a ResultViewerService which takes as parameters the ViewModel to use as content for this popup and a callback to call when the window is closed.
What I want to be able to do, is set a dependency property on the ViewModel and have this re-size the popup windows width based on the property's value. So if the user clicks a button, I can use the ViewModel to double the popup window's width and "expand" the window sideways to show all results. If the user then clicks contract, it returns to the original width.
I can re-size all the content within the window but because of the way I am creating the popup programmatically, I can't figure out how to link the Width of the popup window to the property on the ViewModel contained within the content.
My popup creation service method is as follows
public static Window OpenNew(ResultsViewModel viewModel, ResultsMainViewModel.CallbackResult callback)
{
var resultViewer = new ResultViewer(callback) { DataContext = viewModel };
var panel = new StackPanel { Margin = new Thickness(0), Name = "ParentPanel" };
panel.Children.Add(resultViewer);
var win = new Window
{
Owner = Application.Current.MainWindow,
WindowStyle = WindowStyle.ToolWindow,
WindowStartupLocation = WindowStartupLocation.CenterOwner,
Opacity = 1,
ShowInTaskbar = false,
ResizeMode = ResizeMode.NoResize,
Height = 690,
Width = ResultsConstants.ResultsWidthExpanded,
Margin = new Thickness(0),
Padding = new Thickness(0),
Content = panel,
Topmost = false,
Background =
new ImageBrush
{
ImageSource =
new BitmapImage(new Uri(#"pack://application:,,,/WealthMarginAnalyser;component/Resources/Background2.jpg", UriKind.Absolute))
}
};
win.Closed += resultViewer.ResultViewer_Closed;
win.Show();
return win;
}
The ResultViewer class is the XAML user control that I use for the popup content. So all I am doing in the popup service above is creating a Window programmatically, setting the content as a StackPanel with only one child, the ResultViewer user control which has the DataContext set to the ViewModel. I then set a number of properties on the window programmatically such as width, margin, show in taskbar etc and then show the popup window.
You can see in the above example I am currently hard coding the Width property of the window to the Expanded size, just for testing. But I want this Width property instead to take it's value from the ViewModel's dependency property I have created called ScreenWidth. When I update that property, I want the window to resize accordingly.
How can I achieve this?
I have tried in the past to create Bindings manually eg
Width = new Binding(...)
But I'm not sure if I can achieve this result this way or how I would do it.
The other way is from the ViewModel, to somehow get a reference to the popup window as an object (not pure MVVM of course) and set the Width manually.
Can anyone help me with suggestions?
UPDATE:
I have added the following line to the Window object creation in my service above
DataContext = viewModel
So the window itself has it's datacontext set to the VM, not just the ResultViewer user control. I then have added the following line after the window object creation.
win.SetBinding(FrameworkElement.WidthProperty, new Binding("ScreenWidth"));
This almost works. The window initially loads at the correct size when I open the popup and if I click expand, all the content resizes, but the window itself doesn't. If you close the popup however and re-open it immediately, it comes up at the expanded size. So it seems to be picking up the dependency property fine but ONLY on window creation. If you update the dependency property while the popup is open, it doesn't get the notification that something has changed and to change the width dynamically. I am calling RaisePropertyNotification as required and the user control updates in real-time, so property notification is working, it just doesn't work from the parent window width's perspective.
Is there something else I need to do to wire the INotifyPropertyChanged up to the windows binding I have created programmatically?
At first, you can create new Window using VisualStudio (e.g. Add->New Item->Window(WPF)).
After this you can set all properties of window in XAML:
Width="{Binding Path=MyWidth, Mode=TwoWay}" ShowInTaskbar = "False", ...
Then you can instantiate your window and give it data context:
....
var window = new MyWindow();
window.DataContext = MyViewModel;
win.Closed += resultViewer.ResultViewer_Closed;
win.Show();
return win;
...
Hope this help.
I suggest you do all this in XAML. Create a ResultsWindow, assign its DataContext to the view model and add whichever bindings you need. For example:
<Window xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
x:Class="MyApp.ResultsWindow"
Height="{Binding WindowHeight}"
WindowStyle="ToolWindow"
Background="...">
<ResultViewer />
</Window>
Then in code:
var win = new ResultsWindow { DataContext = viewModel };
win.Show();

How to remove Windows border from WPF UserControl?

To preface this question, I am working on coding the back end of an application whose UI was put together by someone else (I believe using Blend). The application consists of a series of "Screens," whose root element in XAML is "UserControl". There is no use of the "Window" tag anywhere in the source.
What I want to do is remove the Windows border that is added to the outside edge of the application when I run the program. The border currently consists of forward/backward buttons like a web browser, and an X button to close.
All I can find from searches are instructions to add
WindowStyle="None"
to the
<Window>
element. But of course, I don't have one of those, and WindowStyle is not a property of UserControl. Anyone know how to accomplish this with UserControl root elements?
Edit: The StartupUri for the application is
this.StartupUri = new Uri(#"pack://application:,,,/WpfPrototype1.Screens;Component/Screen_1.xaml");
the file it points to does not have a Window tag.
Based on the comments above it seems your MainWindow is created dynamically somewhere, however you can use the Application class to get the applications MainWindow.
var mainWindow = Application.Current.MainWindow;
And you can then set your border style from there
Example:
private void RemoveBorder()
{
var mainWindow = Application.Current.MainWindow;
if (mainWindow != null)//should never be
{
mainWindow.WindowStyle = System.Windows.WindowStyle.None; // removes top bar (icon, title, close buttons etc)
mainWindow.AllowsTransparency = true; //removes the border around the outside
}
}

How do you send information from one window to another in the same program?

In the program I am trying to build, I have a menu button that opens a second window. The user puts information into the second window, presses the "Done" button, and the information is transfered into the main window. The problem I am having is opening the second window. I have both windows build in xaml files in Visual Studio but I can't find a way to show the second window. Using "Window window = new Window" does not fit my needs because 1) I already have the second window built and 2) I have tried this and I cannot figure out how to add children to the window; there is no window.children nor any grid to put the children into. Thank you in advance!
Moments after I pressed post, I thought of something I hadnt tried:
"WindowAdd add = new WindowAdd; //WindowAdd being the second window
add.Show();"
This does exactly what I want it to do. The next problem I have is sending the information the TextBoxes into the MainWindow. I am thinking cookies might work but am unsure. Anyone have any thoughts? Thanks in advance!
You need to create the Window in code, but instead of doing:
Window window = new Window();
You should use:
Window2 window = new Window2(); // Assuming the window's class name is Window2
This will construct and initialize an instance of your new window class, defined in XAML. Once you've done this, you can open the window and you'll see all of your controls.

How do I focus a modal WPF Window when the main application window is clicked

I have my MainApplication Window that launches a new Window with .ShowDialog() so that it is modal.
UploadWindow uploadWindow = new UploadWindow();
uploadWindow.ShowDialog();
Now users are often leaving this window open and it can get lost under other windows. When the MainApplication is clicked you get an error-like beep and are unable to interact with it, so the modal window is blocking properly as expected, but it would be nice if the modal window was focused at this point to show the user it was still open.
Currently it just looks as if the MainApplication window has locked up.
Try setting the dialog's owner:
var uploadWindow = new UploadWindow();
uploadWindow.Owner = this;
uploadWindow.ShowDialog();
I have the problem, that I can't use this, if someone have the same problem, you can use
Window.GetWindow(this)
Since I am using MVVM, I'm not creating the code from the GUI. I used this.
var uploadWindow = new UploadWindow();
uploadWindow.Owner = Application.Current.MainWindow;
uploadWindow.ShowDialog();
If all of the above solutions tried and still facing the same problem
then here is your tested and verified solution
go to your window xaml and add
ResizeMode = "NoResize"
Nowadays you can just set Topmost = true
var uploadWindow = new UploadWindow();
uploadWindow.Topmost = true;

Categories

Resources