I copied the example code from WinUI3 Gallery, it works perfect in MainWindow, but when I do the same thing in a subpage, I received an Exception. I know the problem is with getting the window handle,but I still don't have any idea to solve it.I just wrote the "Hello world" program for C# a few weeks ago, then I got started with WinUI3.
Here is the code
private async void PickAFileButton_Click(object sender, RoutedEventArgs e)
{
// Clear previous returned file name, if it exists, between iterations of this scenario
OutputTextBlock.Text = "";
// Create a file picker
var openPicker = new Windows.Storage.Pickers.FileOpenPicker();
// Retrieve the window handle (HWND) of the current WinUI 3 window.
var window = WindowHelper.GetWindowForElement(this);
var hWnd = WinRT.Interop.WindowNative.GetWindowHandle(window);
// Initialize the file picker with the window handle (HWND).
WinRT.Interop.InitializeWithWindow.Initialize(openPicker, hWnd);
// Set options for your file picker
openPicker.ViewMode = PickerViewMode.Thumbnail;
openPicker.FileTypeFilter.Add("*");
// Open the picker for the user to pick a file
var file = await openPicker.PickSingleFileAsync();
if (file != null)
{
PickAFileOutputTextBlock.Text = "Picked file: " + file.Name;
}
else
{
PickAFileOutputTextBlock.Text = "Operation cancelled.";
}
And in WindowHelper.cs
//*********************************************************
//
// Copyright (c) Microsoft. All rights reserved.
// THIS CODE IS PROVIDED *AS IS* WITHOUT WARRANTY OF
// ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING ANY
// IMPLIED WARRANTIES OF FITNESS FOR A PARTICULAR
// PURPOSE, MERCHANTABILITY, OR NON-INFRINGEMENT.
//
//*********************************************************
using Microsoft.UI;
using Microsoft.UI.Windowing;
using Microsoft.UI.Xaml;
using System;
using System.Collections.Generic;
using WinRT.Interop;
namespace AppUIBasics.Helper
{
// Helper class to allow the app to find the Window that contains an
// arbitrary UIElement (GetWindowForElement). To do this, we keep track
// of all active Windows. The app code must call WindowHelper.CreateWindow
// rather than "new Window" so we can keep track of all the relevant
// windows. In the future, we would like to support this in platform APIs.
public class WindowHelper
{
static public Window CreateWindow()
{
Window newWindow = new Window();
TrackWindow(newWindow);
return newWindow;
}
static public void TrackWindow(Window window)
{
window.Closed += (sender,args) => {
_activeWindows.Remove(window);
};
_activeWindows.Add(window);
}
static public AppWindow GetAppWindow(Window window)
{
IntPtr hWnd = WindowNative.GetWindowHandle(window);
WindowId wndId = Win32Interop.GetWindowIdFromWindow(hWnd);
return AppWindow.GetFromWindowId(wndId);
}
static public Window GetWindowForElement(UIElement element)
{
if (element.XamlRoot != null)
{
foreach (Window window in _activeWindows)
{
if (element.XamlRoot == window.Content.XamlRoot)
{
return window;
}
}
}
return null;
}
static public UIElement FindElementByName(UIElement element, string name)
{
if (element.XamlRoot != null && element.XamlRoot.Content != null)
{
var ele = (element.XamlRoot.Content as FrameworkElement).FindName(name);
if (ele != null)
{
return ele as UIElement;
}
}
return null;
}
static public List<Window> ActiveWindows { get { return _activeWindows; }}
static private List<Window> _activeWindows = new List<Window>();
}
}
UPDATE: Now, I recived this error
------- UPDATE: I rebuild my project and solved this question
My first guess is that, window
is null here,
var window = WindowHelper.GetWindowForElement(this);
and that can be because you didn't use the WindowHelper
to create the parent window.
In App.xaml.cs, instead of
_window = new MainWindow();
use the WindowHelper
to create the window and set the sub page as the Content
.
_window = WindowHelper.CreateWindow();
_window.Content = new SubPage();
By the way, this way you won't be using the MainWindow
class.