You can use the Window class, with EnableWindow to disable/enable parent windows :
This browser is no longer supported.
Upgrade to Microsoft Edge to take advantage of the latest features, security updates, and technical support.
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。
You can use the Window class, with EnableWindow to disable/enable parent windows :
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();
}
Why should I design a UI with XAML if its not shown?
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();
}
}