WPF - Set dialog window position relative to user control - c#

I need help with Setting dialog window position relative to User control.
I want to show my window in the middle user control when a window starts.
How can I find the left and tom location of my User Control?
I use this code in my app but does not work correctly in WPF.
Thank you for help.
private void PossitionWindow(object sender, RoutedEventArgs e)
{
Window wind = new Window();
var location = this.PointToScreen(new Point(0, 0));
wind.Left = location.X;
wind.Top = location.Y - wind.Height;
location.X = wind.Top + (wind.Height - this.ActualHeight) / 2;
location.Y = wind.Left + (wind.Width - this.ActualWidth) / 2;
}

Here is a small example.
// Get absolute location on screen of upper left corner of the UserControl
Point locationFromScreen = userControl1.PointToScreen(new Point(0, 0));
// Transform screen point to WPF device independent point
PresentationSource source = PresentationSource.FromVisual(this);
Point targetPoints = source.CompositionTarget.TransformFromDevice.Transform(locationFromScreen);
// Get Focus
Point focus = new Point();
focus.X = targetPoints.X + (userControl1.Width / 2.0);
focus.Y = targetPoints.Y + (userControl1.Height / 2.0);
// Set coordinates
Window window = new Window();
window.Width = 300;
window.Height = 300;
window.WindowStartupLocation = WindowStartupLocation.Manual;
window.Top = focus.Y - (window.Width / 2.0);
window.Left = focus.X - (window.Height / 2.0);
window.ShowDialog();
Preview

Related

C# - What is the best way to center a form vertical and fixed horizontal programmatically?

I have a windows form and i want to set it in the center vertically and to a fixed point horizontally.
You can see in the code what i have tried unsuccessfully.
What is the best way to solve this?
public Form1()
{
InitializeComponent();
this.StartPosition = FormStartPosition.Manual;
//this.Location = new Point(100, 100);
this.Location = new Point(this.CenterToScreen, 0);
//this.CenterToScreen();
//var rec = Screen.PrimaryScreen.WorkingArea;
//int margain = 10;
//this.Location = new Point(rec.Width - (this.Width + margain), rec.Height - (this.Height + margain));
}

Window open on the Middle of the Right edge of the screen

I have the following code. I'm trying to make the window open on the right side of the primary screen, midway down the side of the screen. It's not moving the starting location of the window at all.
int screenWidth = (int)System.Windows.SystemParameters.PrimaryScreenWidth;
int screenHeight = (int)System.Windows.SystemParameters.PrimaryScreenHeight;
cd.Top = (screenHeight / 2) - (cd.Height / 2);
cd.Left = screenWidth - (cd.Width + 4);
You should place your code in Load event of the window, also this code is a bit more readeable, and works as you wanted to, I checked it.
private void Window_Loaded(object sender, RoutedEventArgs e)
{
var desktopWorkingArea = System.Windows.SystemParameters.WorkArea;
this.Left = desktopWorkingArea.Right - this.Width;
this.Top = desktopWorkingArea.Top + this.Height;
}

Display Form on centre of screen for a dual monitor How to?

I am developing a Windows desktop application dual monitor where I need to display my form sometimes on primary screen and sometimes on secondary,
which works fine but when I display it on my secondary screen I want it to be displayed on centre of my screen which is not working.
Here is my code:
if (Screen.AllScreens.Length > 1)
myForm.Location = Screen.AllScreens[1].WorkingArea.Location;
myForm.StartPosition = FormStartPosition.Manual; // because i wrote manual it is displayed on Top left of my secondaryScreen which is ok
myForm.show();
but I want to diplay it on centre so I wrote
myForm.StartPosition = FormStartPosition.CentreScreen;
//it is not working again a form is displayed on Centre of PrimaryScreen..
Any idea why?
You cannot use StartPosition.CenterScreen because that picks the monitor on which the mouse is currently located. Usually desirable but not what you are asking for. You must use the form's Load event to move it where you want it. Using form's Load is important, you do not know the size of the window until after it is created and the user's preferences are applied and it is rescaled to match the video DPI.
Boilerplate code should look like this:
private void button1_Click(object sender, EventArgs e) {
var form = new Form2();
form.Load += CenterOnSecondMonitor;
form.Show();
}
private void CenterOnSecondMonitor(object sender, EventArgs e) {
var form = (Form)sender;
var area = Screen.AllScreens.Length > 1 ? Screen.AllScreens[1].WorkingArea : Screen.PrimaryScreen.WorkingArea;
form.Location = new Point((area.Width - form.Width) / 2, (area.Height - form.Height) / 2);
form.Load -= CenterOnSecondMonitor;
}
Or you put this code into the form itself, the more common choice:
protected override void OnLoad(EventArgs e) {
var area = Screen.AllScreens.Length > 1 ? Screen.AllScreens[1].WorkingArea : Screen.PrimaryScreen.WorkingArea;
this.Location = new Point((area.Width - this.Width) / 2, (area.Height - this.Height) / 2);
base.OnLoad(e);
}
look for the property of your winform named StartPosition then set it into Center Screen
You could write an extension method:
public static void MoveForm(this Form form, Screen screen = null)
{
if(screen == null)
{
//If we have a single screen, we are not moving the form
if(Screen.AllScreens.Length > 1) return;
screen = Screen.AllScreens[1];
}
var bounds = screen.Bounds;
form.Left = ((bounds.Left + bounds.Right) / 2) - (form.Width / 2);
form.Top = ((bounds.Top + bounds.Bottom) / 2) - (form.Height / 2);
}
private void CenterOnTheCurrentScreen()
{
Rectangle workingArea = Screen.FromControl(this).WorkingArea;
Point center = new Point((workingArea.Width - this.Width) / 2, (workingArea.Height - this.Height) / 2);
this.Location = new Point(workingArea.X + center.X, workingArea.Y + center.Y);
}

How can i set the Form to be in the Center of the Screen?

I'm using this code:
private void notifyIcon1_MouseDoubleClick(object sender, MouseEventArgs e)
{
this.Show();
this.WindowState = FormWindowState.Normal;
//this.Location = new Point(form1_location_on_x, form1_location_on_y);
//this.StartPosition = FormStartPosition.CenterScreen;
Either the line
this.Location = new Point(form1_location_on_x, form1_location_on_y);
or the line
this.StartPosition = FormStartPosition.CenterScreen;
are working when I'm on my original screen resolution 1920x1080, but once I'm changing the resolution to 1024x768, the Form is on the right bottom corner not hidden I see it all but it's not in the center.
form1_location_on_x and on_y are:
form1_location_on_x = this.Location.X;
form1_location_on_y = this.Location.Y;
The question is what should I do to make it work on any other resolution like 1024x768 or any others? I tried many changes but nothing worked so far.
Size screenSize = Screen.PrimaryScreen.WorkingArea.Size;
Location = new Point(screenSize.Width / 2 - Width / 2, screenSize.Height / 2 - Height / 2);
Make sure that you set StartPosition = FormStartPosition.Manual;
Tested and working with 1920x1080 and 1024 x 768
You could calculate the top and left position of your form using this formula:
int formWidth = yourForm.Width;
int formHeight = yourForm.Height;
int screenH = (Screen.PrimaryScreen.WorkingArea.Top +
Screen.PrimaryScreen.WorkingArea.Height) / 2;
int screenW = (Screen.PrimaryScreen.WorkingArea.Left +
Screen.PrimaryScreen.WorkingArea.Width) / 2;
int top = screenH - formWidth / 2;
int left = screenW - formHeight / 2;
yourForm.Location = new Point(top, left);
Of course, these days, you have the problem of dual monitors.
I don't know if you want your form to appear always on the primary screen or you want the form appear in the current screen (the one where the form is currently displayed). In this second case you need to find where your form is displayed
private void CenterForm(Form yuorForm)
{
foreach(var s in Screen.AllScreens)
{
if(s.WorkingArea.Contains(yourForm.Location))
{
int screenH = s.WorkingArea.Height / 2;
int screenW = s.WorkingArea.Width / 2;
int top = (screenH + s.WorkingArea.Top) - formWidth / 2;
int left = (screenW + s.WorkingArea.Left) - formHeight / 2;
yourForm.Location = new Point(top, left);
break;
}
}
}
EDIT: Thanks to #alex I will complete the answer with the information on SystemEvents class
If you want to be notified by the system when the user suddenly change the resolution of your screen you could subscribe to the event SystemEvents.DisplaySettingsChanged (using Microsoft.Win32; needed)
SystemEvents.DisplaySettingsChanged += new EventHandler(SystemEvents_DisplaySettingsChanged);
and then handle the reposition of your form in the event
// This method is called when the display settings change.
void SystemEvents_DisplaySettingsChanged(object sender, EventArgs e)
{
RecenterForm(yourForm);
}
try using one of these after the resize:
this.CenterToScreen();
or
this.CenterToParent();
You can use StartPosition property of Form objects. It determines the position of a form. Set it's value to CenterScreen if you want your form to open in the center of the screen

How to get the TopLeft screen-coordinate of a PictureBox on a Windows Forms

I have a a PictureBox on my Windows Forms.
I am drawing a Rectangle on the PictureBox, with ControlPaint.DrawReversibleFrame(), and want to code some boundaries, so I am only drawing on the PictureBox and not the whole screen.
How do I find the screen-coordinates of the topleft point of the PictureBox?
EDIT with solution: Here's my solution, if anybody need to code some PictureBox boundaries.
if (_isDragging) // If the mouse is being dragged, undraw and redraw the rectangle as the mouse moves.
{
pictureBoxMap.Refresh();
ControlPaint.DrawReversibleFrame(_theRectangleScreenCoords, BackColor, FrameStyle.Dashed); // Hide the previous rectangle by calling the DrawReversibleFrame method with the same parameters.
Point endPoint = ((Control)sender).PointToScreen(new Point(e.X, e.Y));
var topLeftPictureBoxMap = pictureBoxMap.PointToScreen(new Point(0, 0));
int width = endPoint.X - _startPointTheRectangleScreenCoords.X;
int height = endPoint.Y - _startPointTheRectangleScreenCoords.Y;
// limit rectangle in x-axis
var diff_x = pictureBoxMap.Width - (_startPointTheRectangleScreenCoords.X - topLeftPictureBoxMap.X);
var diff_x_2 = (pictureBoxMap.Width - (_startPointTheRectangleScreenCoords.X - topLeftPictureBoxMap.X)) - pictureBoxMap.Width;
if (width > diff_x)
{
width = diff_x;
}
else if(width < diff_x_2)
{
width = diff_x_2;
}
// limit rectangle i y-aksen
var diff_Y = pictureBoxMap.Height - (_startPointTheRectangleScreenCoords.Y - topLeftPictureBoxMap.Y);
var diff_Y_2 = (pictureBoxMap.Height - (_startPointTheRectangleScreenCoords.Y - topLeftPictureBoxMap.Y)) - pictureBoxMap.Height;
if (height > diff_Y)
{
height = diff_Y;
}
else if(height < diff_Y_2)
{
height = diff_Y_2;
}
_theRectangleScreenCoords = new Rectangle(
_startPointTheRectangleScreenCoords.X,
_startPointTheRectangleScreenCoords.Y,
width,
height);
ControlPaint.DrawReversibleFrame(_theRectangleScreenCoords, Color.Red, FrameStyle.Dashed); // Draw the new rectangle by calling DrawReversibleFrame again.
}
Use Control.PointToScreen( new Point(0, 0) ) where Control is your PictureBox.
See http://msdn.microsoft.com/en-us/library/system.windows.forms.control.pointtoscreen.aspx

Categories

Resources