Reputation: 1950
How can I set the window size in MAUI?
Background info: I only care about Windows for this application - I chose MAUI so I could use Blazor for a desktop application. For some reason the default window size is massive (takes up almost all of my 1440p screen space). The application I'm making only needs about 600x600. Having a way to make the window size fixed would also be helpful although I'm happy to have the app simply be responsive.
Upvotes: 37
Views: 36591
Reputation: 724
.NET7 in Visual Studio 2022 17.4 introduces a more elegant way to do this than .NET6 implementations. For a Windows specific app, just add the following code to App.xaml.cs
namespace sampleCode;
public partial class App : Application
{
public App()
{
InitializeComponent();
MainPage = new AppShell();
}
protected override Window CreateWindow(IActivationState activationState)
{
var window = base.CreateWindow(activationState);
const int newWidth = 800;
const int newHeight = 600;
window.Width = newWidth;
window.Height = newHeight;
return window;
}
}
UPDATE 11/30/2024. This approach is deprecated in .NET9 so a new long term approach will be needed.
UPDATE 1/24/2025. For .NET 9, see Bhavaresh's answer. https://stackoverflow.com/a/79332866/18248161
Updated example using Bhavaresh's recommendation for .NET 9
protected override Window CreateWindow(IActivationState? activationState)
{
const int newHeight = 800;
const int newWidth = 600;
var newWindow = new Window(new AppShell())
{
Height = newHeight,
Width = newWidth
};
return newWindow;
}
Upvotes: 56
Reputation: 1
If you want to set just a maximum height and width for your app you might consider doing it like this:
#if WINDOWS
const int maximumWidth = 1920;
const int maximumHeight = 1020;
var window = sender as Window;
// change window size.
window.MaximumWidth = maximumWidth;
window.MaximumHeight = maximumHeight;
#endif
Upvotes: 0
Reputation: 1255
As mentioned in documentation here.
From .NET 9
preferred way to set first page of app is to override CreateWindow and pass the first page to newly created Window object.
Here, you can set window's height and width (size) as well.
protected override Window CreateWindow(IActivationState? activationState)
{
const int newheight = 715;
const int newwidth = 1290;
var wins = new Window(//object of your first page);
wins.Height = wins.MinimumHeight = wins.MaximumHeight = newheight;
wins.Width = wins.MinimumWidth = wins.MaximumWidth = newwidth;
return wins;
}
Upvotes: 1
Reputation: 21233
UPDATE
For .Net 8, see also jeff's answer.
Other answers are also worth looking at.
Updated for Maui GA (I'll add to that discussion too):
#if WINDOWS
using Microsoft.UI;
using Microsoft.UI.Windowing;
using Windows.Graphics;
#endif
namespace YourAppNameHere;
public partial class App : Application
{
const int WindowWidth = 400;
const int WindowHeight = 750;
public App()
{
InitializeComponent();
Microsoft.Maui.Handlers.WindowHandler.Mapper.AppendToMapping(nameof(IWindow), (handler, view) =>
{
#if WINDOWS
var mauiWindow = handler.VirtualView;
var nativeWindow = handler.PlatformView;
nativeWindow.Activate();
IntPtr windowHandle = WinRT.Interop.WindowNative.GetWindowHandle(nativeWindow);
var windowId = Microsoft.UI.Win32Interop.GetWindowIdFromWindow(windowHandle);
var appWindow = Microsoft.UI.Windowing.AppWindow.GetFromWindowId(windowId);
appWindow.Resize(new Windows.Graphics.SizeInt32(WindowWidth, WindowHeight));
#endif
});
MainPage = new MainPage();
}
...
OR if want to base it on requested dimensions of MainPage, before appending handler could do:
MainPage = new MainPage();
var width = (int)MainPage.WidthRequest;
var height = (int)MainPage.HeightRequest;
then use those dimensions (probably add some padding to get whole window size, because MainPage is client area).
NOTE: I was testing for Windows, so in the drop-down at upper-left of source text editor pane, I had selected ... (net6.0-windows10.0.19041.0)
. That's why I did not notice that I needed #if
around the using
s, to avoid errors on Android etc.
Upvotes: 33
Reputation: 711
Since September 2022, it can be done more simply:
public partial class App : Application
{
public App()
{
InitializeComponent();
MainPage = new AppShell();
}
protected override Window CreateWindow(IActivationState activationState)
{
Window window = base.CreateWindow(activationState);
window.Activated += Window_Activated;
return window;
}
private async void Window_Activated(object sender, EventArgs e)
{
#if WINDOWS
const int DefaultWidth = 1024;
const int DefaultHeight = 800;
var window = sender as Window;
// change window size.
window.Width = DefaultWidth;
window.Height = DefaultHeight;
// give it some time to complete window resizing task.
await window.Dispatcher.DispatchAsync(() => { });
var disp = DeviceDisplay.Current.MainDisplayInfo;
// move to screen center
window.X = (disp.Width / disp.Density - window.Width) / 2;
window.Y = (disp.Height / disp.Density - window.Height) / 2;
#endif
}
}
Related ticket: https://github.com/dotnet/maui/pull/4942
Upvotes: 9
Reputation: 310
This is How we did it :
https://github.com/BhangeeF16/MAUI-DOT-NET/blob/main/SampleApp/MauiProgram.cs
In MauiProgram.cs
> CreateMauiApp
#if WINDOWS
builder.ConfigureLifecycleEvents(events =>
{
events.AddWindows(wndLifeCycleBuilder =>
{
wndLifeCycleBuilder.OnWindowCreated(window =>
{
IntPtr nativeWindowHandle = WinRT.Interop.WindowNative.GetWindowHandle(window);
WindowId win32WindowsId = Win32Interop.GetWindowIdFromWindow(nativeWindowHandle);
AppWindow winuiAppWindow = AppWindow.GetFromWindowId(win32WindowsId);
if(winuiAppWindow.Presenter is OverlappedPresenter p)
{
p.Maximize();
//p.IsAlwaysOnTop=true;
p.IsResizable=false;
p.IsMaximizable = false;
p.IsMinimizable=false;
}
else
{
const int width = 1920;
const int height = 1080;
winuiAppWindow.MoveAndResize(new RectInt32(1920 / 2 - width / 2, 1080 / 2 - height / 2, width, height));
}
});
});
});
#endif
Upvotes: 6
Reputation: 96
I hate that I can't just put this minor edit in a comment instead of providing a whole new answer, but that's S.O. for you.
You can control the window size and enabling of maximise/minimise/resize by changing your Windows platform specific implementation to the following (in Platforms/Windows/App.xaml.cs
). This avoids having to wrap platform specific code in #if feature gates.
public partial class App : MauiWinUIApplication
{
/// <summary>
/// Initializes the singleton application object. This is the first line of authored code
/// executed, and as such is the logical equivalent of main() or WinMain().
/// </summary>
public App()
{
this.InitializeComponent();
Microsoft.Maui.Handlers.WindowHandler.Mapper.AppendToMapping(nameof(IWindow), (handler, view) =>
{
var mauiWindow = handler.VirtualView;
var nativeWindow = handler.PlatformView;
nativeWindow.Activate();
// allow Windows to draw a native titlebar which respects IsMaximizable/IsMinimizable
nativeWindow.ExtendsContentIntoTitleBar = false;
IntPtr windowHandle = WinRT.Interop.WindowNative.GetWindowHandle(nativeWindow);
WindowId windowId = Microsoft.UI.Win32Interop.GetWindowIdFromWindow(windowHandle);
AppWindow appWindow = Microsoft.UI.Windowing.AppWindow.GetFromWindowId(windowId);
// set a specific window size
appWindow.Resize(new SizeInt32(480, 720));
if (appWindow.Presenter is OverlappedPresenter p)
{
p.IsResizable = false;
// these only have effect if XAML isn't responsible for drawing the titlebar.
p.IsMaximizable = false;
p.IsMinimizable = false;
}
});
}
protected override MauiApp CreateMauiApp() => MauiProgram.CreateMauiApp();
}
Upvotes: 6
Reputation: 11
[Agree to the previous answer regarding edit and comments (also rep requirements for comments)]
For those who prefer to use the Platforms/Windows/App.xaml.cs approach, you can easily get the screen size by adding in an 'Activated' event handler to the code (simple to expand if you want the displayInfo.Density too):
public partial class App : MauiWinUIApplication
{
Microsoft.UI.Xaml.Window nativeWindow;
int screenWidth, screenHeight;
const int desiredWidth = 480;
const int desiredHeight = 720;
/// <summary>
/// Initializes the singleton application object. This is the first line of authored code
/// executed, and as such is the logical equivalent of main() or WinMain().
/// </summary>
public App()
{
this.InitializeComponent();
Microsoft.Maui.Handlers.WindowHandler.Mapper.AppendToMapping(nameof(IWindow), (handler, view) =>
{
IWindow mauiWindow = handler.VirtualView;
nativeWindow = handler.PlatformView;
nativeWindow.Activated += OnWindowActivated;
nativeWindow.Activate();
// allow Windows to draw a native titlebar which respects IsMaximizable/IsMinimizable
nativeWindow.ExtendsContentIntoTitleBar = false;
IntPtr windowHandle = WinRT.Interop.WindowNative.GetWindowHandle(nativeWindow);
WindowId windowId = Microsoft.UI.Win32Interop.GetWindowIdFromWindow(windowHandle);
AppWindow appWindow = Microsoft.UI.Windowing.AppWindow.GetFromWindowId(windowId);
// set a specific window size
appWindow.MoveAndResize(new RectInt32((screenWidth - desiredWidth) / 2, (screenHeight - desiredHeight) / 2, desiredWidth, desiredHeight));
if (appWindow.Presenter is OverlappedPresenter p)
{
p.IsResizable = false;
// these only have effect if XAML isn't responsible for drawing the titlebar.
p.IsMaximizable = false;
p.IsMinimizable = false;
}
});
}
private void OnWindowActivated(object sender, Microsoft.UI.Xaml.WindowActivatedEventArgs args)
{
// Retrieve the screen resolution
var displayInfo = DeviceDisplay.Current.MainDisplayInfo;
screenWidth = (int)displayInfo.Width;
screenHeight = (int)displayInfo.Height;
// Remove this event handler since it is not needed anymore
nativeWindow.Activated -= OnWindowActivated;
}
Upvotes: 1
Reputation: 347
✅ After .NET 7 Window On Launch can be easily resized like this On App.xaml.cs Page :
public partial class App : Application
{
protected override Window CreateWindow(IActivationState activationState)
{
var window = base.CreateWindow(activationState);
// Change the window Size
window.Width = 600; window.Height = 600;
// BONUS -> Center the window
var displayInfo = DeviceDisplay.Current.MainDisplayInfo;
window.X = (displayInfo.Width / displayInfo.Density - window.Width) / 2;
window.Y = (displayInfo.Height / displayInfo.Density - window.Height) / 2;
return window;
}
}
Upvotes: 1
Reputation: 2203
How to set initial window size and center it (maui 7.0.59):
public partial class App : Application {
public App() {
InitializeComponent();
MainPage = new AppShell();
}
protected override Window CreateWindow(IActivationState activationState) {
var window = base.CreateWindow(activationState);
window.Created += Window_Created;
return window;
}
private async void Window_Created(object sender, EventArgs e) {
const int defaultWidth = 1200;
const int defaultHeight = 800;
var window = (Window)sender;
window.Width = defaultWidth;
window.Height = defaultHeight;
window.X = -defaultWidth;
window.Y = -defaultHeight;
await window.Dispatcher.DispatchAsync(() => {});
var displayInfo = DeviceDisplay.Current.MainDisplayInfo;
window.X = (displayInfo.Width / displayInfo.Density - window.Width) / 2;
window.Y = (displayInfo.Height / displayInfo.Density - window.Height) / 2;
}
}
Upvotes: 3
Reputation: 326
If you only want to do this for the Desktop Platforms, then you can do something similar to @ToolmakerSteve but per-platform by overriding the OnLaunched function within the Platforms/Windows/App.xaml.cs
for example.
using Microsoft.UI;
using Microsoft.UI.Windowing;
using Windows.Graphics;
using WinRT.Interop;
//...
protected override void OnLaunched(LaunchActivatedEventArgs args)
{
base.OnLaunched(args);
var currentWindow = Application.Windows[0].Handler.PlatformView;
IntPtr _windowHandle = WindowNative.GetWindowHandle(currentWindow);
var windowId = Win32Interop.GetWindowIdFromWindow(_windowHandle);
AppWindow appWindow = AppWindow.GetFromWindowId(windowId);
appWindow.Resize(new SizeInt32(350, 600));
}
These methods of resizing are still not ideal as it will flicker when it's changing window size. This is simply because of the time taken between OnLaunch being fired and the window being resized by native win32 API calls. However, moving it directly to the Platform-specific code is a bit more semantic.
Unlike the other answer we cannot get the Requested dimensions from client pages to use as our Window dimensions.
Upvotes: 2