0

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. enter image description here 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 errorenter image description here

------- UPDATE: I rebuild my project and solved this question

Wu Xiuheng
  • 53
  • 5
  • 1
    Means `window` is null. Apparently this WindowHelper class doesn't handle the first window. You could get rid of this helper and use another approach like this https://stackoverflow.com/questions/74273875/retrive-window-handle-in-class-library-winui3/74286947#74286947 – Simon Mourier Aug 08 '23 at 06:11

1 Answers1

1

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.

Andrew KeepCoding
  • 7,040
  • 2
  • 14
  • 21
  • But I only find `public static WindowEx MainWindow { get; } = new MainWindow();` in **App.xaml.cs**, maybe we can get MainWindow's hwnd without using **WindowHelper.cs** – Wu Xiuheng Aug 08 '23 at 05:54
  • 1
    Yes, you can. Check my answer [here](https://stackoverflow.com/a/76448851/2411960). – Andrew KeepCoding Aug 08 '23 at 06:02
  • 1
    Of course. Just [call the GetWindowHandle method on the WinRT.Interop.WindowNative C# interop class](https://learn.microsoft.com/en-us/windows/apps/develop/ui-input/retrieve-hwnd#winui-3-with-c). As @AndrewKeepCoding said, `WindowHelper.GetWindowForElement` doesn't find the element window in `_activeWindows`. – YangXiaoPo-MSFT Aug 08 '23 at 06:06
  • I tried, but why am I getting this error[screenshot](https://img1.imgtp.com/2023/08/08/e9DKsg3C.jpg) – Wu Xiuheng Aug 08 '23 at 06:28
  • Can't see the link due to security issues. What does the error say? If it's complicated to do this in the comments, update you question. – Andrew KeepCoding Aug 08 '23 at 06:32
  • Sorry, update my question – Wu Xiuheng Aug 08 '23 at 06:59
  • [I cannot reproduce using the code.](https://i.stack.imgur.com/Qbiz8.png) – YangXiaoPo-MSFT Aug 08 '23 at 07:50
  • OH, I rebuild my project and now it works! Maybe it's the problem with Visual Studio – Wu Xiuheng Aug 08 '23 at 08:10