Is there a way (either C# or XAML) I can maximize a UWP app window even after I resized and closed it previously on desktop?
I have tried with ApplicationViewWindowingMode.FullScreen but this makes the app go entire full screen and covers the Windows Taskbar too.
You can use another value PreferredLaunchViewSize from ApplicationViewWindowingMode and then set ApplicationView.PreferredLaunchViewSize but the key is to find out what the size is going to be.
Theoretically, you could use a really big number and window would just extend to the max it could be. However, it's probably safer to just calculate the screen dimensions in effective pixels.
So if you just call the following method before InitializeComponent(); on your main Page, it should maximize the window on startup.
private static void MaximizeWindowOnLoad()
{
// Get how big the window can be in epx.
var bounds = ApplicationView.GetForCurrentView().VisibleBounds;
ApplicationView.PreferredLaunchViewSize = new Size(bounds.Width, bounds.Height);
ApplicationView.PreferredLaunchWindowingMode = ApplicationViewWindowingMode.PreferredLaunchViewSize;
}
Note the app somehow remembers these settings even after you uninstalled it. If you ever want to change back to the default behavior (app starts up with the previous window size), simply call ApplicationView.PreferredLaunchWindowingMode = ApplicationViewWindowingMode.Auto; once and remove all the code.
Update
Looks like in the latest Windows 10 build, ApplicationView.GetForCurrentView().VisibleBounds no longer returns the full window size in effective pixels anymore. So we now need a new way to calculate it.
Turns out it's quite straightforward since the DisplayInformation class also gives us the screen resolution as well as the scale factor.
The following is the updated code -
public MainPage()
{
MaximizeWindowOnLoad();
InitializeComponent();
void MaximizeWindowOnLoad()
{
var view = DisplayInformation.GetForCurrentView();
// Get the screen resolution (APIs available from 14393 onward).
var resolution = new Size(view.ScreenWidthInRawPixels, view.ScreenHeightInRawPixels);
// Calculate the screen size in effective pixels.
// Note the height of the Windows Taskbar is ignored here since the app will only be given the maxium available size.
var scale = view.ResolutionScale == ResolutionScale.Invalid ? 1 : view.RawPixelsPerViewPixel;
var bounds = new Size(resolution.Width / scale, resolution.Height / scale);
ApplicationView.PreferredLaunchViewSize = new Size(bounds.Width, bounds.Height);
ApplicationView.PreferredLaunchWindowingMode = ApplicationViewWindowingMode.PreferredLaunchViewSize;
}
}
If you want to MAXIMISE your app on launch you can use the following:
ApplicationView.PreferredLaunchWindowingMode = ApplicationViewWindowingMode.Maximized;
But be sure to put it into the Loaded Event for your Page or it will not work!
I've too few points to comment directly. None of the above resized to a maximized view for me (or the below single-line ApplicationViewWindowingMode.Maximized method), but I have used some of the answers to come up with something that worked for me. It is still very clunky however. The screen size given in 'DisplayInformation' is too big to allow the page to be resized directly to it. Trying to do it didn't work and I had to take 60 off height and width to get it to return 'true', therefore I have the following bit of nonsense which worked, maybe it will help someone else find a better answer. It goes in the page/window loaded event. Nothing else needs to be added elsewhere.
private void Page_Loaded(object sender, RoutedEventArgs e)
{
var view = ApplicationView.GetForCurrentView();
var displayInfo = DisplayInformation.GetForCurrentView();
double x = ActualWidth;
double y = ActualHeight;
bool answer = true;
// Get the screen resolution (APIs available from 14393 onward).
var resolution = new Size(displayInfo.ScreenWidthInRawPixels-60, displayInfo.ScreenHeightInRawPixels-60);
answer = view.TryResizeView(resolution); //This should return true if the resize is successful
if (answer)
{
x = displayInfo.ScreenWidthInRawPixels - 60;
y = displayInfo.ScreenHeightInRawPixels - 60;
}
answer = true;
while (answer == true)
{
x++;
answer = view.TryResizeView(new Size { Width = x, Height = y });
}
x = x - 1;
answer = true;
while (answer == true)
{
y++;
answer = view.TryResizeView(new Size { Width = x, Height = y });
}
Adding the following line to the OnLaunched event under App.xaml.cs did it for me.
ApplicationView.PreferredLaunchWindowingMode = ApplicationViewWindowingMode.FullScreen;
NOTE: Make sure to add it before the following line
Window.Current.Activate();
If you like to go fullscreen at the runtime use the following line.
ApplicationView.GetForCurrentView().TryEnterFullScreenMode();
I have this one liner that works as I expected Justins code to, but for some reason, when using Justins answer, my window would not be maximized... But then I changed something that did make it maximized but I lost all my fluent design such as Acrylic and RevealHighlite...
So I came up with this one liner which keeps all of my fluent design principles happy:
ApplicationView.GetForCurrentView().TryEnterFullScreenMode();
Something to note:
I did try Justins answer, and I am using his method of MaximizeWindowOnLoad() which I have called straight after the initializeComponent();
Full overview:
public class()
{
this.InitializeComponent();
MaximizeWindowOnLoad();
}
private static void MaximizeWindowOnLoad()
{
ApplicationView.GetForCurrentView().TryEnterFullScreenMode();
}
Related
I'm trying to display an overlay during an auto login HTTP call.
I've found this code, which seems outdated somehow, but found nothing more recent.
Anyway, the Overlay is showing but not covering the whole screen as expected.
The calling code is this:
AppDelegate.FinishedLaunching
var avc = new AutoLoginViewController();
var navController = new UINavigationController(avc);
AutoLoginViewController.ViewDidLoad
var bounds = UIScreen.MainScreen.Bounds;
// show the loading overlay on the UI thread using the correct orientation sizing
loadPop = new LoadingOverlay(bounds, NSBundle.MainBundle.GetLocalizedString("connecting"));
View.Add(loadPop);
But the result is the following:
If I set a breakpoint in the LoadingOverlay constructor, I can see that the screen bounds (iPhone 6) are fine:
{{X=0,Y=0,Width=375,Height=667}}
public class LoadingOverlay : UIView
{
public LoadingOverlay(CGRect frame, string text) : base(frame)
{
// configurable bits
BackgroundColor = UIColor.Black;
Alpha = 0.75f;
AutoresizingMask = UIViewAutoresizing.FlexibleDimensions;
...
}
}
Clearly the UIView width is incorrect.
Because we're in 2020, maybe there is another way.
Any help appreciated.
EDIT: The app breaks on iPhone 8 iOS 13.3 simulator, So I can't say if this is tied to a particular screen size (1x in my case).
Cause :
It seems that you didn't set the LaunchImage , So whether on a simulator or real device , the value of bounds is a static value .
Solution:
The easiest way is set the size of overlay as bounds of View .
var bounds = View.Bounds;
Or you could set all size of LaunchImage of different screen .
My winform can't change the size. The wince device is 480*764. I debugged and got a new size:
But the size still unchanged. What happened?
Try putting your sizing code into the constructor not the Load event. Don't think that FormBorderStyle needs to be sizable (is this even supported in the .NET Compact Framework which I assume you are using?). Our forms have a style of FixedDialog. If you need to centre the form you can use this helper function which you call immediately after setting the size:
public static void SetFormPosition(Form frmChild)
{
// Set the form position on the Windows CE panel
if (frmChild != null)
{
// Get the size of the screen (should be 480x768)
Rectangle rctScreen = Screen.PrimaryScreen.WorkingArea;
// Now calculate the position of the form
int nPosX = ((rctScreen.Width - frmChild.Width) / 2);
int nPosY = ((rctScreen.Height - frmChild.Height) / 2);
// Set the position
frmChild.Location = new Point(nPosX, nPosY);
}
}
I have found that this works PART of the time by inheriting the Windows Forms mouse point and subtracting out the height and width of my window to set the left and top (since my window's size is fixed):
MyWindowObjectThatInheritsWindow window = new MyWindowObjectThatInheritsWindow();
System.Windows.Point mouseLocation = GetMousePositionWindowsForms();
window.Left = mouseLocation.X - 300;
window.Top = mouseLocation.Y - 240;
window.Show();
Edit: Here is the code for getting the mouse position...
public System.Windows.Point GetMousePositionWindowsForms()
{
System.Drawing.Point point = System.Windows.Forms.Control.MousePosition;
return new System.Windows.Point(point.X, point.Y);
}
Note that this works by making the bottom right edge of the window touch the top left of your mouse cursor. But this breaks for different screen resolutions, or maybe multiple monitors with different resolutiosn? I haven't fully narrowed it down yet, but I just tried this same code on another PC, and it seems to spawn the window not to the top left of the mouse cursor, but to the bottom left of it, and a good distance past it...
I should probably add that my window sizes to content, width and height, so I can't just use the ActualWidth and ActualHeight properties since they're not available. Perhaps the issue is in getting that sizing right? Is there any way to do that? I know for sure the 300 and 240 is correct according to my main PC with two monitors running 1920x1080 resolutions, as I have calculated the widths and heights of all the objects in my window which I have explicitly sized. Edit: Just tried explicitly setting the height and width to 240/300, to ensure that the window is no longer sized to content, and I still have this issue when subtracting out the actual height and width!
Any ideas?
In the end, this did the trick:
protected override void OnContentRendered(EventArgs e)
{
base.OnContentRendered(e);
MoveBottomRightEdgeOfWindowToMousePosition();
}
private void MoveBottomRightEdgeOfWindowToMousePosition()
{
var transform = PresentationSource.FromVisual(this).CompositionTarget.TransformFromDevice;
var mouse = transform.Transform(GetMousePosition());
Left = mouse.X - ActualWidth;
Top = mouse.Y - ActualHeight;
}
public System.Windows.Point GetMousePosition()
{
System.Drawing.Point point = System.Windows.Forms.Control.MousePosition;
return new System.Windows.Point(point.X, point.Y);
}
Can you not use something like this?:
Point mousePositionInApp = Mouse.GetPosition(Application.Current.MainWindow);
Point mousePositionInScreenCoordinates =
Application.Current.MainWindow.PointToScreen(mousePositionInApp);
I haven't been able to test it, but I think it should work.
UPDATE >>>
You don't have to use the Application.Current.MainWindow as the parameter in these methods... it should still work if you have access to a Button or another UIElement in a handler:
Point mousePositionInApp = Mouse.GetPosition(openButton);
Point mousePositionInScreenCoordinates = openButton.PointToScreen(mousePositionInApp);
Again, I haven't been able to test this, but if that fails as well, then you can find one more method in the How do I get the current mouse screen coordinates in WPF? post.
You can also do this by slightly modifying your initial example and positioning the window before showing it.
MyWindowObjectThatInheritsWindow window = new MyWindowObjectThatInheritsWindow();
var helper = new WindowInteropHelper(window);
var hwndSource = HwndSource.FromHwnd(helper.EnsureHandle());
var transformFromDevice = hwndSource.CompositionTarget.TransformFromDevice;
System.Windows.Point wpfMouseLocation = transformFromDevice.Transform(GetMousePositionWindowsForms());
window.Left = wpfMouseLocation.X - 300;
window.Top = wpfMouseLocation.Y - 240;
window.Show();
I'm storing the last position for each window.
Next time the user opens the window, the last position is restored.
If the user changes his screen (from dual screen to one screen) or just to a smaller resolution, the form is nowhere to be seen...
How can I detect this? I don't like to store user settings, depending on his environment.
Thanks in advance
Let's start from scratch, you want two settings to store the state of the window. Let's call them Location (type Point, default = 0,0) and Size (type Size, default = 0, 0). You want to save them when the window is resized, avoiding storing state if the window is minimized:
protected override void OnResizeEnd(EventArgs e) {
if (this.WindowState != FormWindowState.Minimized) {
Properties.Settings.Default.Location = this.Location;
Properties.Settings.Default.Size = this.Size;
Properties.Settings.Default.Save();
}
base.OnResizeEnd(e);
}
Restore the state in the form's OnLoad method. You'll want to use Screen.FromPoint() to find the screen bounds back. Add extra code to ensure the window doesn't get too large and locates properly when the screen has disappeared:
protected override void OnLoad(EventArgs e) {
if (Properties.Settings.Default.Size != Size.Empty) {
Screen scr = Screen.FromPoint(Properties.Settings.Default.Location);
int width = Math.Min(Properties.Settings.Default.Size.Width, scr.WorkingArea.Width);
int height = Math.Min(Properties.Settings.Default.Size.Height, scr.WorkingArea.Height);
this.Size = new Size(width, height);
if (scr.WorkingArea.Contains(Properties.Settings.Default.Location))
this.Location = Properties.Settings.Default.Location;
else this.Location = new Point(scr.Bounds.Left + (scr.Bounds.Width - width) / 2,
scr.Bounds.Top + (scr.Bounds.Height - height) / 2);
}
base.OnLoad(e);
}
Use the Bounds property from System.Windows.Forms.Screen.PrimaryScreen to see what the bounds of the screen is, compare that to the position/size of your form and compensate where needed.
To get at the bounds of other screens, use the Screen.AllScreens property on the PrimaryScreen property to gain access to other Screen objects representing multiple screens.
For example, this may be as simple as checking that the Location you want to change to is on an available screen:
foreach (var screen in Screen.AllScreens)
{
if (screen.Bounds.Contains(this.Location))
{
return; // on a screen, so don't update location
}
}
// not found on a screen, so assume screen was removed and move to the primary screen
this.Location = Screen.PrimaryScreen.Bounds.Location;
You can, of course, make this more complicated by deciding which screen contains more of the form than any other (based on Bounds) and make a determination that way; but, without more details about exactly what you want, I can't suggest specifics.
I am developing a clock Timer. It is working fine however I am having a issue when the form which is normally small to sit in the corner of the screen out of the way is maximised. Is there a way when it is maximised that I can move the location of the Activity (where all the info is enetered) - I can move that start pause and stop/reset button and I can also move the labels which countdown the time and make them a lot bigger on the maximised display. I have two images - background small and background large which are changing fine on the maximise - I used the code below too hook into the size change event - however the commented out is not working - it does not let be hard code the X,Y co-ordinates of where i would like the activity on maximise...is there something I am missing?
Many Thanks - Colly.
private void CountDownTimer_SizeChanged(object sender, EventArgs e)
{
Image Max = new Bitmap(#"C:\Users\colinmck\Desktop\Timer\CountDownTimer\IgnitionTeamLRG.bmp");
Image Min = new Bitmap(#"C:\Users\colinmck\Desktop\Timer\CountDownTimer\IgnitionTeamSML.bmp");
if (WindowState == FormWindowState.Maximized)
{
BackgroundImage = Max;
//Not Working!!!!!!!!!!!!!
//Activity.Location.X = 60;
//Activity.Location.Y = 65;
}
else
{
BackgroundImage = Min;
}
}
Location.X and Location.Y are read only properties. You should try...
Activity.Location = new Point(60, 65);
Perhaps also take a look into the Anchor property for auto resizing of controls: http://www.tutorialized.com/view/tutorial/C-Resizing-controls-with-form-Anchor-property/52689