UWP AppWindow获取正确的监视器/显示区域

发布于 2025-01-24 03:17:27 字数 5199 浏览 0 评论 0原文

IDEA非常简单打开应用中的一个或多个窗口,在关闭应用程序时节省其大小,位置和监视器位置,然后在再次打开应用程序时,每个窗口都应在相同的位置,大小和监视器上打开被关闭了,我能够做大小位置成功,但 Monitor/displayRegion 即使我的次要窗口也为我提供了错误的监视器在第二监视器上,它返回第一个监视器(显示区域),我只需要在保存位置数据时弄清楚,我如何确定我的特定次要 appwindow 在哪个监视/显示区域?

在应用程序关闭时,按照代码运行

internal static void UpdateAppWindowsPlacements()
    {
        foreach (var item in AppWindowViewModels)
        {
            ApplicationData.Current.LocalSettings.Values[$"AppWindow_SecondaryView_Show_{item.Key}"] = item.AppWindow != null;
            if (item.AppWindow != null)
            {
                var placement = item.AppWindow.GetPlacement();
                var regions = new List<DisplayRegion>(); 
                foreach (var dr in item.AppWindow.WindowingEnvironment.GetDisplayRegions())
                {
                    regions.Add(dr);// this list is just for testing, it gives me boh monitors/DisplayRegions, but no way to find out where this window resides.
                }
                //Size is full screen size and can be bigger bcz it also includes taskbar etc.
                //Display region excludes taskbar etc
                var displayRegion = placement.DisplayRegion;
                var displayRegionWidth = displayRegion.WorkAreaSize.Width;
                var displayRegionHeight = displayRegion.WorkAreaSize.Height;

                var sizeWidth = placement.Size.Width;
                var sizeHeight = placement.Size.Height;

                ApplicationData.Current.LocalSettings.Values[$"AppWindow_SecondaryView_Width_{item.Key}"] = sizeWidth > displayRegionWidth ? displayRegionWidth : sizeWidth;
                ApplicationData.Current.LocalSettings.Values[$"AppWindow_SecondaryView_Height_{item.Key}"] = sizeHeight > displayRegionHeight ? displayRegionHeight : sizeHeight;

                ApplicationData.Current.LocalSettings.Values[$"AppWindow_SecondaryView_X_{item.Key}"] = placement.Offset.X;
                ApplicationData.Current.LocalSettings.Values[$"AppWindow_SecondaryView_Y_{item.Key}"] = placement.Offset.Y;
            }
        }
    }

打开辅助窗口并根据保存位置将其定位

internal static async Task OpenSecondaryWindows(int total)
    {
        for (int i = 0; i < total; i++)
        {
            var appWindowViewModel = new AppWindowViewModel(i.ToString());
            AppWindowViewModels.Add(appWindowViewModel);
            var open = ApplicationData.Current.LocalSettings.Values[$"AppWindow_SecondaryView_Show_{i}"];
            if (open == null)
            {
                ApplicationData.Current.LocalSettings.Values[$"AppWindow_SecondaryView_Show_{i}"] = true;
                open = true;
            }
            if ((bool)open)
            {
                await View(appWindowViewModel);
            }
        }
    }
    private static async Task View(AppWindowViewModel appWindowViewModel)
    {
        if (appWindowViewModel.AppWindow is null)
        {
            appWindowViewModel.AppWindow = await AppWindow.TryCreateAsync();
            var frame = new Frame();
            frame.Navigate(typeof(SecondaryPage), appWindowViewModel.Key);
            ElementCompositionPreview.SetAppWindowContent(appWindowViewModel.AppWindow, frame);

            appWindowViewModel.AppWindow.Closed += delegate
            {
                frame.Content = null;
                appWindowViewModel.AppWindow = null;
            };
        }

        var shown = await appWindowViewModel.AppWindow.TryShowAsync();

        var windowWidth = ApplicationData.Current.LocalSettings.Values[$"AppWindow_SecondaryView_Width_{appWindowViewModel.Key}"];
        var windowHeight = ApplicationData.Current.LocalSettings.Values[$"AppWindow_SecondaryView_Height_{appWindowViewModel.Key}"];
        if (windowWidth is double wWidth && windowHeight is double wHeight)
        {
            appWindowViewModel.AppWindow.RequestSize(new Size(wWidth, wHeight));
        }

        var xposition = ApplicationData.Current.LocalSettings.Values[$"AppWindow_SecondaryView_X_{appWindowViewModel.Key}"];
        var yposition = ApplicationData.Current.LocalSettings.Values[$"AppWindow_SecondaryView_Y_{appWindowViewModel.Key}"];
        if (xposition is double xpos && yposition is double ypos)
        {
            var placement = appWindowViewModel.AppWindow.GetPlacement();
            appWindowViewModel.AppWindow.RequestMoveRelativeToDisplayRegion(placement.DisplayRegion, new Point(xpos, ypos));
        }
        else
        {
            appWindowViewModel.AppWindow.RequestMoveAdjacentToCurrentView();
        }
    }

我有一个示例UWP应用程序: https://github.com/touseeefbsb/appwindowremember

您可以克隆它并运行 Multiappwindowspample2 打开次要窗口。它将按预期在主窗口旁边打开1个辅助窗口,现在将第二个窗口移动到第二监视器,然后关闭您的主窗口它将询问您是否要保存位置,请按,是

现在,再次运行该应用程序,然后在文本框中输入“ 1”,然后再次按下按钮,请注意您的第一个监视器/显示上的辅助窗口打开。虽然目的是在第二次关闭时在第二监视器上打开它。

Idea is very simple open one or more windows in the app, save their size, position and monitor placement when closing the app, and then when they are opened again, every window should open on the same position, size and monitor they were closed on, I was able to do the size and position succesfully but monitor/DisplayRegion is giving me incorrect monitor, even when my secondary window is on 2nd monitor, It returns the first monitor (display region), I just need to figure out at the time of saving the placement data, how can I figure out that my specific secondary AppWindow is on which monitor/DisplayRegion?

Following code runs when app is closing

internal static void UpdateAppWindowsPlacements()
    {
        foreach (var item in AppWindowViewModels)
        {
            ApplicationData.Current.LocalSettings.Values[
quot;AppWindow_SecondaryView_Show_{item.Key}"] = item.AppWindow != null;
            if (item.AppWindow != null)
            {
                var placement = item.AppWindow.GetPlacement();
                var regions = new List<DisplayRegion>(); 
                foreach (var dr in item.AppWindow.WindowingEnvironment.GetDisplayRegions())
                {
                    regions.Add(dr);// this list is just for testing, it gives me boh monitors/DisplayRegions, but no way to find out where this window resides.
                }
                //Size is full screen size and can be bigger bcz it also includes taskbar etc.
                //Display region excludes taskbar etc
                var displayRegion = placement.DisplayRegion;
                var displayRegionWidth = displayRegion.WorkAreaSize.Width;
                var displayRegionHeight = displayRegion.WorkAreaSize.Height;

                var sizeWidth = placement.Size.Width;
                var sizeHeight = placement.Size.Height;

                ApplicationData.Current.LocalSettings.Values[
quot;AppWindow_SecondaryView_Width_{item.Key}"] = sizeWidth > displayRegionWidth ? displayRegionWidth : sizeWidth;
                ApplicationData.Current.LocalSettings.Values[
quot;AppWindow_SecondaryView_Height_{item.Key}"] = sizeHeight > displayRegionHeight ? displayRegionHeight : sizeHeight;

                ApplicationData.Current.LocalSettings.Values[
quot;AppWindow_SecondaryView_X_{item.Key}"] = placement.Offset.X;
                ApplicationData.Current.LocalSettings.Values[
quot;AppWindow_SecondaryView_Y_{item.Key}"] = placement.Offset.Y;
            }
        }
    }

Opening secondary windows and positioning them as per saved position

internal static async Task OpenSecondaryWindows(int total)
    {
        for (int i = 0; i < total; i++)
        {
            var appWindowViewModel = new AppWindowViewModel(i.ToString());
            AppWindowViewModels.Add(appWindowViewModel);
            var open = ApplicationData.Current.LocalSettings.Values[
quot;AppWindow_SecondaryView_Show_{i}"];
            if (open == null)
            {
                ApplicationData.Current.LocalSettings.Values[
quot;AppWindow_SecondaryView_Show_{i}"] = true;
                open = true;
            }
            if ((bool)open)
            {
                await View(appWindowViewModel);
            }
        }
    }
    private static async Task View(AppWindowViewModel appWindowViewModel)
    {
        if (appWindowViewModel.AppWindow is null)
        {
            appWindowViewModel.AppWindow = await AppWindow.TryCreateAsync();
            var frame = new Frame();
            frame.Navigate(typeof(SecondaryPage), appWindowViewModel.Key);
            ElementCompositionPreview.SetAppWindowContent(appWindowViewModel.AppWindow, frame);

            appWindowViewModel.AppWindow.Closed += delegate
            {
                frame.Content = null;
                appWindowViewModel.AppWindow = null;
            };
        }

        var shown = await appWindowViewModel.AppWindow.TryShowAsync();

        var windowWidth = ApplicationData.Current.LocalSettings.Values[
quot;AppWindow_SecondaryView_Width_{appWindowViewModel.Key}"];
        var windowHeight = ApplicationData.Current.LocalSettings.Values[
quot;AppWindow_SecondaryView_Height_{appWindowViewModel.Key}"];
        if (windowWidth is double wWidth && windowHeight is double wHeight)
        {
            appWindowViewModel.AppWindow.RequestSize(new Size(wWidth, wHeight));
        }

        var xposition = ApplicationData.Current.LocalSettings.Values[
quot;AppWindow_SecondaryView_X_{appWindowViewModel.Key}"];
        var yposition = ApplicationData.Current.LocalSettings.Values[
quot;AppWindow_SecondaryView_Y_{appWindowViewModel.Key}"];
        if (xposition is double xpos && yposition is double ypos)
        {
            var placement = appWindowViewModel.AppWindow.GetPlacement();
            appWindowViewModel.AppWindow.RequestMoveRelativeToDisplayRegion(placement.DisplayRegion, new Point(xpos, ypos));
        }
        else
        {
            appWindowViewModel.AppWindow.RequestMoveAdjacentToCurrentView();
        }
    }

I have a sample uwp app : https://github.com/touseefbsb/AppWindowRemember

you can clone it and run the MultiAppWindowSample2 project, enter "1" in the text box and press the button Open Secondary Windows. it will open 1 secondary window alongside the main window as expected, now move the 2nd window to your 2nd monitor and then close your main window it will ask whether you want to save the placement, press Yes.

Now run the app again, and enter "1" in textbox and press button again, notice the secondary window opens on your first monitor/display. While the aim is to open it on the 2nd monitor as it was closed the last time.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

老街孤人 2025-01-31 03:17:27

UWP AppWindow获取正确的监视器/显示区域

问题是,即使您已经将AppWindow移动到了当前 appwindow appwindow 的display区域始终是第一个监视器第二个显示器。我将报告这个问题。当前有工作是在第二个监视器中显示AppWindow,首先将第二个监视器的ID记录到本地设置中。

在测试期间)。您可以使用它来指导哪个是第二监视器。

private DisplayRegion GetOtherDisplayRegion(DisplayRegion currentAppDisplayRegion)
{
    // Get the list of all DisplayRegions defined for the WindowingEnvironment that our application is currently in
    IReadOnlyList<DisplayRegion> displayRegions = ApplicationView.GetForCurrentView().WindowingEnvironment.GetDisplayRegions();
    foreach (DisplayRegion displayRegion in displayRegions)
    {
        if (displayRegion != currentAppDisplayRegion && displayRegion.IsVisible)
        {
            return displayRegion;
        }
    }

    return null;
}

有关更多信息,请参阅官方代码样本

UWP AppWindow Get correct monitor/Display region

The problem is the DisplayRegion of current AppWindow is always the first monitor even if you have moved the AppWindow into the second monitor. I will report this problem. and currently there is work around is show AppWindow in the second monitor at first and record the second monitor's id into local setting.

During the testing ApplicationView.GetForCurrentView().GetDisplayRegions()[0] could return correct DisplayRegion for current main app window (does not return correct value when move current into other monitor). you can use it to direct which is second monitor.

private DisplayRegion GetOtherDisplayRegion(DisplayRegion currentAppDisplayRegion)
{
    // Get the list of all DisplayRegions defined for the WindowingEnvironment that our application is currently in
    IReadOnlyList<DisplayRegion> displayRegions = ApplicationView.GetForCurrentView().WindowingEnvironment.GetDisplayRegions();
    foreach (DisplayRegion displayRegion in displayRegions)
    {
        if (displayRegion != currentAppDisplayRegion && displayRegion.IsVisible)
        {
            return displayRegion;
        }
    }

    return null;
}

For more please refer to official code sample .

年少掌心 2025-01-31 03:17:27

该错误仅出现在Windows 11上。设备ID错误,但偏移量正确,因此我们可以使用正确的窗口偏移量和设备偏移量来计算正确的设备。

The bug only appeared on Windows 11. The device id is wrong but the offset is right, so we can use the right window offset and device offset to calculate the right device.

巴黎盛开的樱花 2025-01-31 03:17:27

首先,您必须保存displayRegion.displayMonitorDeviceId(或在重新加载上恢复的内容)。我成功使用了ID。

然后,您可以通过AppWindow.windowingenvironment.getDisPlayRegions()或Windows.ui.windowmanagement.windowingenvironment.getDisplayRegions()获得可用的显示区域列表。此列表不可查看,而是与Foreach一起使用的。

步行列表并找到匹配的设备,然后找到RequestMovereLativEtodIsplayRegion。结构中的ID需要重新铸造至“字符串”才能正确比较。

传递的坐标是相对于显示区域[监视器]的,即使监视器从主监视器位于负空间中,也将从0,0偏移。

我昨天刚刚找到了这个样本,并弄清楚了解决方案。我需要对原始文章和github示例提供更新,但我没有将链接带回家。

First, you must save the DisplayRegion.DisplayMonitorDeviceId (or something to recover on reload). I successfully used the ID.

Then you can get a list of DisplayRegions availible through either the AppWindow.WindowingEnvironment.GetDisplayRegions() or Windows.UI.WindowManagement.WindowingEnvironment.GetDisplayRegions(). This list is not debug viewable, but does work with foreach.

Walk the list and find the matching device, then RequestMoveRelativeToDisplayRegion. The ids in the struct require recasting to "string" to compare correctly.

The coordinates passed are relative to the DisplayRegion [monitor] and will be offset from 0,0 even if the monitor is positioned in negative space from the main monitor.

I just found this sample yesterday and figured out the solution. I need to offer an update to the original article and github sample, but I didn't bring the link home.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文