Opening all windows at the same time

Eduardo Gomez Romero 185 Reputation points
2024-04-03T13:14:19.27+00:00

I found this post searching

https://learn.microsoft.com/en-us/answers/questions/1411868/how-to-activate-a-window-in-net-maui

it seems like a good solution

 if (!WindowHelper.SecondWindowCreated) {
        // Create the second window
        var newPage = _items[name!];
        var secondWindow = WindowHelper.CreateWindow(newPage, "second", 300, 300);
        secondWindow.Created += (s, e) => { WindowHelper.SecondWindowCreated = true; };
        secondWindow.Destroying += (s, e) => { WindowHelper.SecondWindowCreated = false; };
        Application.Current?.OpenWindow(secondWindow);
    } else {
        // Activate the existing second window
        MauiProgram.secondWindow.Activate();
    }


it does open the correct window, it is opening the same every time

        public static MauiWinUIWindow secondWindow;
        public static MauiApp CreateMauiApp() {
            var builder = MauiApp.CreateBuilder();
            builder
                .UseMauiApp<App>()
                .ConfigureFonts(fonts => {
                    fonts.AddFont("OpenSans-Regular.ttf", "OpenSansRegular");
                    fonts.AddFont("OpenSans-Semibold.ttf", "OpenSansSemibold");
                }).ConfigureLifecycleEvents(e => {
#if WINDOWS
                    e.AddWindows(windows => windows.OnWindowCreated(window => {
                        var mauiWinUIWindow = window as MauiWinUIWindow;
                        if (mauiWinUIWindow?.Title == "second") {
                            secondWindow = mauiWinUIWindow;
                        }
                    }));
#endif
                });
#if DEBUG
            builder.Logging.AddDebug();
#endif
            builder.Services.AddTransient<MainViewModel>();
            builder.Services.AddSingleton<MainPage>();


 public static bool SecondWindowCreated { get; set; }

 public static Window CreateWindow(Page view, string title, double height, double width, double x = 0, double y = 0) {

     var displayInfo = DeviceDisplay.MainDisplayInfo;

     if (height == 0 && width == 0) {

         width = displayInfo.Width;
         height = displayInfo.Height;
     }

     var newWindow = new Window() {

         Page = view,

         Title = title,

         Height = height,

         Width = width,

         X = x,

         Y = y,

     };

     return newWindow;
 }


If for example I have my application in Fullscreen move, and decide to open 8 little windows it will open all (Obviously I know that I have to click on them to interact with them, but a want to see all of them

look

User's image I am going to open the "Marion Window"User's image

if I click in the dot net

I get the Maio windowsUser's image

I also found a bug, if I close the mario window and try to open it again. I get

User's image

apparenly my new Window is null
User's image

.NET MAUI
.NET MAUI
A Microsoft open-source framework for building native device applications spanning mobile, tablet, and desktop.
2,845 questions
{count} votes

Accepted answer
  1. Yonglun Liu (Shanghai Wicresoft Co,.Ltd.) 35,046 Reputation points Microsoft Vendor
    2024-04-08T08:51:01.8766667+00:00

    Hello,

    Only one variable is needed to activate two windows. For multi-window requirements, you need to record the opened windows through a data structure. In the following example, I use two pages, differentiate them through different Title attributes and save them into a dictionary.

    Before providing the key code, I need to explain two core issues.

    If I open the Mario window, and close it, and open again I get this error.

    This null pointer error is because you used a dictionary to create the page.

        Dictionary<string, Page> _items = new() {
    
            {"mario.png", new Page1()},
            {"dotnet_bot.png", new Page_2()},
        };
    

    Your expected behavior should be to create a new page using the value in the ImageButton. However, the actual function of this code is to create a new page only when declared. So when you close the window and reopen it, the context will be null because the page has been Disposed.

    every window I opened. for windows and Mac

    Mac does not support programmatic activation of windows.

    First of all, I would like to inform you that the user has to touch the screen to active a session on iOS/MacCatalyst. Please watch the Apple's Window Management in Your Multitasking App video around 4:50. Therefore, you cannot bring an existing window to the foreground programmatically.

    For implementing this function on Windows, please refer to the following key code:

    API you need to implement for WindowHelper.

      public static class WindowHelper
        {
            private static Dictionary<string, Window> _windows = new Dictionary<string, Window>();
    #if WINDOWS
            private static Dictionary<string, MauiWinUIWindow> _windowsUIWindow = new Dictionary<string, MauiWinUIWindow>();
            public static void AddUIWindow(string title,MauiWinUIWindow value)
            {
                if (!_windowsUIWindow.ContainsKey(title))
                {
                    value.Closed += (s, e) => {
                        _windowsUIWindow.Remove(title);
                    };
                    _windowsUIWindow.Add(title, value);
                }
            }
            public static MauiWinUIWindow GetExistedWinUIWindow(string title)
            {
                return _windowsUIWindow[title];
            }
    #endif
            public static bool WindowCreated(string title)
            {
                return _windows.ContainsKey(title);
            }
            public static Window GetExistedWindow(string title) { 
                return _windows[title];
            }
            public static Window CreateWindow(Page view, string title, double height, double width, double x = 0, double y = 0)
            {
                if (!_windows.ContainsKey(view.Title))
                {
                    var displayInfo = DeviceDisplay.MainDisplayInfo;
    
                   if (height == 0 && width == 0)
                    {
    
                       width = displayInfo.Width;
                        height = displayInfo.Height;
                    }
    
                   var newWindow = new Window()
                    {
                        Page = view,
                        Title = title,
                        Height = height,
                        Width = width,
                        X = x,
                        Y = y,
                    };
                    newWindow.Destroying += (s, e) => { _windows.Remove(view.Title); };
                    _windows.Add(view.Title, newWindow);
                    return newWindow;
                }
                else
                {
                    return _windows[view.Title];
                }
    
            }
       }
    
    

    Add WinUI window to dictionary when creating new window:

    .ConfigureLifecycleEvents(e => {
    #if WINDOWS
                        e.AddWindows(windows => windows.OnWindowCreated(window => {
                            var mauiWinUIWindow = window as MauiWinUIWindow;
                            WindowHelper.AddUIWindow(mauiWinUIWindow.Title, mauiWinUIWindow);
                        }));
    #endif
                    });
    

    Create a new page through the Switch method in the page to avoid the null pointer problem.

    public partial class MainPage : ContentPage
        {
            public MainPage()
            {
                InitializeComponent();
            }
            Page GetPageByName(string Sourcename)
            {
                switch (Sourcename) {
                    case "File: test.png":
                        return new Page1(); // 
                    case "File: dotnet_bot.png":
                        return new Page2();
                    default:
                        return new Page1();
                }
            }
            private void ImageButton_Clicked(object sender, EventArgs e)
            {
                var btn = sender as ImageButton;
                var newPage = GetPageByName(btn.Source.ToString());
                if (!WindowHelper.WindowCreated(newPage.Title))
                {
                    // Create the new window
                    var newWindow = WindowHelper.CreateWindow(newPage, newPage.Title, 300, 300);   
                    Application.Current?.OpenWindow(newWindow);
                }
                else
                {
    #if WINDOWS
                    // Activate the existing second window
                    WindowHelper.GetExistedWinUIWindow(newPage.Title).Activate();
    #endif
                }
           }
        }
    
    

    Best Regards,

    Alec Liu.


    If the answer is the right solution, please click "Accept Answer" and kindly upvote it. If you have extra questions about this answer, please click "Comment".

    Note: Please follow the steps in our documentation to enable e-mail notifications if you want to receive the related email notification for this thread.


0 additional answers

Sort by: Most helpful