Sellorio
Sellorio

Reputation: 1950

MAUI .NET Set Window Size

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

Answers (11)

jeff28273
jeff28273

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

Mittelfeld55
Mittelfeld55

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

Bhavanesh N
Bhavanesh N

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

ToolmakerSteve
ToolmakerSteve

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 usings, to avoid errors on Android etc.

Upvotes: 33

Michael Tsai
Michael Tsai

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

BNG016
BNG016

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

user2170796
user2170796

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

Tregajorran
Tregajorran

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

THENETSPIDER
THENETSPIDER

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

KTCO
KTCO

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

rlaphoenix
rlaphoenix

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

Related Questions