[Winui3]How to show a model window?

lei han 46 Reputation points
2022-07-01T08:22:42.937+00:00
PrivacyWindow::PrivacyWindow() {  
    InitializeComponent();  
	//......  
    window_handle_ = GetWindowHandle();  
    auto window_id = winrt::Microsoft::UI::GetWindowIdFromWindow(window_handle_);  
    app_window_ = winrt::Microsoft::UI::Windowing::AppWindow::GetFromWindowId(window_id);  
    auto presenter = app_window_.Presenter().as<winrt::Microsoft::UI::Windowing::OverlappedPresenter>();  
    presenter.IsResizable(false);  
    presenter.IsMaximizable(false);  
    presenter.IsMinimizable(false);  
    presenter.IsModal(true); // crash here  
    app_window_.SetPresenter(presenter);  
	//......  
}  

I tried IsModal of OverlappedPresenter, but it crashes.
I think the reason is that the owner of the window is not set to be MainWindow. But I don't know how to set it up.
ps:I'm sure what I want to pop up is a modal window and not a dialog。

Windows App SDK
Windows App SDK
A set of Microsoft open-source libraries, frameworks, components, and tools to be used in apps to access Windows platform functionality on many versions of Windows. Previously known as Project Reunion.
838 questions
0 comments No comments
{count} votes

Accepted answer
  1. Castorix31 87,721 Reputation points
    2022-07-01T08:47:02.093+00:00

    You can use the Window class, with EnableWindow to disable/enable parent windows :

    216893-modal-windows.gif

    2 people found this answer helpful.

4 additional answers

Sort by: Most helpful
  1. 徐凤辉 1 Reputation point
    2023-03-31T08:18:32.1133333+00:00
    0 comments No comments

  2. eFail 0 Reputation points
    2023-07-27T05:41:53.7633333+00:00

    For anyone else coming here looking for a straightforward answer, here it is. In order to create a modal window, you have to create the window manually using the AppWindow class. The Window class can't be used to create it.

    When creating the AppWindow, pass it a newly constructed OverlappedPresenter that has IsModal=true. And here's the most important part: when creating the AppWindow, you must use the overloaded version of the Create() method that takes in the ID of an owner window. Set the ID to the ID of the window that the modal window will be associated with. If you don't do this, you will get the following error which explains absolutely nothing about what the problem is:

    System.ArgumentException: 'Value does not fall within the expected range.'

    If you're creating a modal window, make it non-resizable if you can. Otherwise, you have to deal with the strange behavior that comes from the user minimizing it.

    Full working solution:

    // Proper option for modal windows in most cases is "Dialog" (non-resizable).
    // "this" is some other Window.
    {
        var presenter = OverlappedPresenter.CreateForDialog(); 
        presenter.IsModal = true;
    
        var appWindow = AppWindow.Create(presenter, this.AppWindow.Id); 
        appWindow.Show();
    }
    

  3. Torsten Krause 0 Reputation points
    2024-05-13T07:15:02.6066667+00:00

    Why should I design a UI with XAML if its not shown?

    0 comments No comments

  4. Zakaria TAHRI 0 Reputation points
    2025-03-04T11:50:50.2033333+00:00

    This code uses Windows App SDK 1.6.5

    using System;
    using System.Runtime.InteropServices;
    using Microsoft.UI;
    using Microsoft.UI.Windowing;
    using Microsoft.UI.Xaml;
    using WinRT.Interop;
    
    namespace YourNamespace;
    
    public sealed partial class ModalWindow : Window
    {
        private AppWindow appWindow;
    
        public ModalWindow()
        {
            this.InitializeComponent();
            appWindow = GetAppWindowForCurrentWindow();
            appWindow.Resize(new Windows.Graphics.SizeInt32(400,300));
    
            OverlappedPresenter presenter = OverlappedPresenter.CreateForDialog();
    
            // Set this modal window's owner (the main application window).
            // The main window can be retrieved from App.xaml.cs if it's set as a static property.
            SetOwnership(appWindow, App.m_window);
    
            // Make the window modal (blocks interaction with the owner window until closed).
            presenter.IsModal = true;
    
            // Apply the presenter settings to the AppWindow.
            appWindow.SetPresenter(presenter);
    
            // Show the modal window.
            appWindow.Show();
    
            Closed += ModalWindow_Closed;
        }
    
        private AppWindow GetAppWindowForCurrentWindow()
        {
            IntPtr hWnd = WindowNative.GetWindowHandle(this);
            WindowId myWndId = Win32Interop.GetWindowIdFromWindow(hWnd);
            return AppWindow.GetFromWindowId(myWndId);
        }
    
        // Sets the owner window of the modal window.
        private static void SetOwnership(AppWindow ownedAppWindow, Window ownerWindow)
        {
            // Get the HWND (window handle) of the owner window (main window).
            IntPtr parentHwnd = WindowNative.GetWindowHandle(ownerWindow);
    
            // Get the HWND of the AppWindow (modal window).
            IntPtr ownedHwnd = Win32Interop.GetWindowFromWindowId(ownedAppWindow.Id);
    
            // Set the owner window using SetWindowLongPtr for 64-bit systems
            // or SetWindowLong for 32-bit systems.
            if (IntPtr.Size == 8) // Check if the system is 64-bit
            {
                SetWindowLongPtr(ownedHwnd, -8, parentHwnd); // -8 = GWLP_HWNDPARENT
            }
            else // 32-bit system
            {
                SetWindowLong(ownedHwnd, -8, parentHwnd);
            }
        }
    
        // Import the Windows API function SetWindowLongPtr for modifying window properties on 64-bit systems.
        [DllImport("User32.dll", CharSet = CharSet.Auto, EntryPoint = "SetWindowLongPtr")]
        public static extern IntPtr SetWindowLongPtr(IntPtr hWnd, int nIndex, IntPtr dwNewLong);
    
        // Import the Windows API function SetWindowLong for modifying window properties on 32-bit systems.
        [DllImport("User32.dll", CharSet = CharSet.Auto, EntryPoint = "SetWindowLong")]
        public static extern IntPtr SetWindowLong(IntPtr hWnd, int nIndex, IntPtr dwNewLong);
    
        private void ModalWindow_Closed(object sender, WindowEventArgs args)
        {
            // Reactivate the main application window when the modal window closes.
            App.StartupWindow.Activate();
        }
    
        private void OKButton_Click(object sender, RoutedEventArgs e)
        {
            this.Close();
        }
    
        private void CancelButton_Click(object sender, RoutedEventArgs e)
        {
            this.Close();
        }
    }
    
    
    0 comments No comments

Your answer

Answers can be marked as Accepted Answers by the question author, which helps users to know the answer solved the author's problem.