I think there is a bug with the Window.Width and Window.Height of wpf. I need my window to cover my entire desktop (there are two monitors) but first let me show you why I think there is a bug.
First let me show you the resolution of my monitors: (both have the same resolution)
this is the window on visual studio that I am working with
I don't know if you guys know AutoIt but it is a nice program to automate simple stuff. so if I want to resize my MainWindow to cover all the space in my first monitor (same thing as if I where maximizing a window) I will execute this method on autoit:
and when I execute that code my window that I am creating in visual studio extends and it appears exactly as if it where to be maximized.
so far the coordinates seem to be working.
now when I do the same thing with c# on wpf:
public static void setWindowSize(System.Windows.Window w)
{
w.Left = 0;
w.Top =0;
w.Width = 1920;
w.Height = 1079;
}
The parameter w will be the MainWindow. When I execute that take a look how the window get's resized:
I placed the older image next to it so that you guys can compare it. Why are the dimensions not the same? I belive that the Window.Width and Window.Height properties do not work correctly. or what am I doing wrong?
If you want to cover your main monitor then
Width = SystemParameters.PrimaryScreenWidth, Height = SystemParameters.PrimaryScreenHeight
if you want to cover both monitors
Width = SystemParameters.VirtualScreenWidth, Height = SystemParameters.VirtualScreenHeight
try out this
Width = SystemParameters.PrimaryScreenWidth,
Height = SystemParameters.PrimaryScreenHeight,
Related
I'm trying to open another window from a menu control located on my main window and I want this window's startup position to be centered relative to the main window. I have achieved this by setting the Owner property of the secondary window to my main window and setting the WindowStartupLocation property in XAML to CenterOwner, like this:
PopupWindow about = new PopupWindow();
about.Owner = Application.Current.MainWindow;
about.Show();
about.Owner = null;
The problem with this is that a window with an Owner seems to always stay on top of the Owner and whenever the Owner window is minimized, the Owned window also minimizes. To fix this I remove the Owner after the window is shown. The code seems to work fine, but it also feels a little bit like a hack.
I know there is a way to do this by setting the startup location to manual and then calculating where the window should be positioned, but I'm starting the secondary window from a popup control and I couldn't find a way to reference a window other than main. I think I could loop through the Windows collection and check a property to see if it's the window I need, but that almost seems worse than what I'm doing here.
Is there a better or more standard way of doing this?
There is no "best" way per se to do this kind of thing. It actually doesn't have any built-in function. All of the methods for doing this are kind of "hacks", you might say. A standard way of doing this is getting the coordinates of the main window and based on the about window calculate where you want its location to be. Or you can do it your way too. Here is a simple example:
int width = mainwindow.getWidth() / 2;
int height = mainWindow.getHeight() / 2;
int locationWidth = width - about.getWidth() / 2;
int locationHeight = height - about.getHeight() / 2;
// Then set it
about.Location = new Cursor(locationWidth, locationHeight);
I don't remember exactly how to set the location, because I'm not on my normal computer. But you get the idea. Also, we do width - about.getWidth() / 2, because in C# the location is set not from the center but from the top left corner. Hope it helps.
I would like to create an application that have a small window displayed at the bottom corner of desktop. On startup, the window shall be very small and ideally, just a couple of pixels in width.
Here is the code I used to do it:
public partial class DurationT64 : Form
{
private Size fullSize;
private Point fullPos;
private Point compactPos;
public DurationT64()
{
InitializeComponent();
var workingArea = Screen.PrimaryScreen.WorkingArea;
this.MinimumSize = new Size(0, this.Height);
this.MaximumSize = new Size(this.Width, this.Height);
// fullPos: the window location when it is in full size form.
fullPos = new Point(workingArea.Right - this.Width, workingArea.Bottom - this.Height);
this.Location = fullPos;
// fullSize: the size of the windown when it is in full size form.
fullSize = new Size(this.Width, this.Height);
this.Size = fullSize;
// compactPos: the window location when it is in compact size form.
compactPos = new Point(workingArea.Right - 30, fullPos.Y);
this.Width = 1;
this.Location = compactPos;
}
}
As you can see that in this example, I intended to create a window of just 1 pixel in width, placed closed to the right edge of the primary monitor.
However, I realized that the window doesn't go as small as I was expected. It goes down to 20 pixels wide but no less than that. Please refer to this screen capture image below for example:
an image shows that the window is wider than it suppose to be
I did some research regards to this problem and noticed that there was a solution proposed by Zach Johnson (#zach-johnson) back in 2009. Here is the link to it Overcome OS Imposed Windows Form Minimum Size Limit.
However, nether methods proposed in that link (the intercepting WM_ message one proposed by Zach and the SetBoundsCore one proposed by #Ace) works for me.
Can anyone please give me some solution to this question? Preferably, a solution purely based on C#/Winform and does not rely on native Win32 window message loop, if possible.
Many thanks!
It is rather straight-forward, Winforms ensures that the window cannot be made smaller than the system-imposed minimum size of a window, exposed as the SystemInformation.MinWindowTrackSize property in .NET. This is a "safety" setting, it ensures that the user cannot make the window too small when he resizes it, thus losing control over it. Same consideration applies to code.
Bypassing this limit requires no magic, you need to do two things:
Set the FormBorderStyle property to None so the user cannot resize the window.
Set the size after the window is created. The Load event is best.
Some comments about your existing code: be careful about tinkering with the Width/Height/Size properties, you are doing too much of it in your constructor and it cannot work correctly. In the constructor they don't yet match the actual size of the window. And will not be close at all on modern machines with high-resolution monitors, auto-scaling to match the DPI of the video adapter is important today. You have to postpone until the window is created and scaling is complete, the Load event is the proper place for code like this. One of the few reasons to actually use Load.
And note that your Location property calculation is inadequate, it does not consider the location of the taskbar. It doesn't work on my machine, I like the taskbar on the right.
Minimum repro:
public partial class Form1 : Form {
public Form1() {
InitializeComponent();
this.FormBorderStyle = FormBorderStyle.None;
}
protected override void OnLoad(EventArgs e) {
this.Width = 1;
base.OnLoad(e);
}
}
Do keep in mind that you'll need hawk-eyes to find it back on the screen :)
I have made a GUI app (WIN FORM) which is running fine on 12 inch screen(no cropping of the form) but on other Laptops having screen > 12 inches Win Form is going beyond the taskbar and some portion of the Form is not visible to the user.I have fixed it currently by squeezing certain UI boxes on the Form .But why this is happening?How can I auto-rectify it for all the PC models.
You may want to have a look at Form.AutoSize property. Also, in the link, look at AutoSizeMode.
However, to be able to fix this you may need to rewrite the whole form.
It sounds like a fixed sized dialog (at least I suppose it wouldn't be a problem with a resizable form).
You should adjust your form height to the desktop size (and maybe width too). The code below will shrink the form if it is too large and displays the scrollbar to make possible to access the remaining area.
protected override void OnShown(EventArgs e)
{
base.OnShown(e);
AdjustHeight();
}
private void AdjustHeight()
{
Rectangle screen = Screen.FromControl(this).WorkingArea;
int screenHeight = screen.Height;
if (screenHeight < Height)
{
Height = screenHeight;
AdjustFormScrollbars(true); // not needed if AutoScroll property is true
}
}
I made an application on 1366x768 resolution which is my laptop's current resolution, being a beginner, i din't care about the resolution issues.
When i took that application and executed it on a lower resolution PC , then all was messed up. The form was going somewhere else, most of its part hidden.
So, please help me to how to make my winform resolution independent, or how to get the current screen resolution and set it into my winform so that it changes itself accordingly.
The property
Screen.PrimaryScreen.WorkingArea
is very useful for form sizing and positioning.
For example this code:
this.Width = Screen.PrimaryScreen.WorkingArea.Width/2;
this.Height = Screen.PrimaryScreen.WorkingArea.Height/2;
this.Top = (Screen.PrimaryScreen.WorkingArea.Top + Screen.PrimaryScreen.WorkingArea.Height)/4;
this.Left = (Screen.PrimaryScreen.WorkingArea.Left + Screen.PrimaryScreen.WorkingArea.Width)/4;
(The Screen class is a member of System.Windows.Forms namespace)
will place the form in which it is executed in the middle of the screen and size it to half the screen.
The WorkingArea var is used to exclude stuff like the task bar and other docked items on the desktop when calculating the size of the screen.
Hope this helps.
See here: http://social.msdn.microsoft.com/forums/en-US/vbgeneral/thread/1be40692-80fa-42ba-b316-9fe13a935b4f/ and here: http://social.msdn.microsoft.com/Forums/en-US/winforms/thread/d5f2cd8d-d24d-4574-ba3a-96e22e3d1b56/
General approach is to start with the min resolution you'll be working with. Then you can scale your forms up (using proper docking and anchors).
I've decided to teach myself C# by writing a music player in Visual Studio 2010. I went with WPF because from what I hear it sounds like it will be a good base to skin from.
I want to program my window with the behavior where if the window comes to the edge of a screen (within 10px or so) it will snap to the screen edge. What's the best way to go about this?
Well there are a few areas you need to address. First to get notifications that the edge is coming close to the screen:
Get notifications that window's size is changing. This one is easy - just use Window.SizeChanged event.
Get notifications that window position is changing. This one is a bit tricky and I am not sure how to achieve it, might need to P/Invoke into Win32 API.
Then, there is a list of TODOs to work out if the window edge is close to the screen edge.
Whether or not there are multiple monitors and if the window is solely contained within on monitor. This answer will help you get the monitor information.
Handle the action of snapping the edge. Will need a bit of rect arithmetic acrobatics for this one. Then you either set Window.Top, Window.Left, Window.Height or Window.Width.
You will need conditional code for each edge but it will look something like this:
void SnapWindow(Window window, Size monitorSize) {
if (window.Left < c_SnapThreshold && window.Left > 0)
window.Left = 0;
if (window.Left + window.Width > (monitorSize.Width - SnapThreshold) && window.Left + window.Width < monitorSize.Width)
window.Width = monitorSize.Width - window.Left; //docks the right edge
//..etc
}
}