【问题标题】:WPF create one Window for each screen, and center them on each screenWPF 为每个屏幕创建一个 Window,并在每个屏幕上居中
【发布时间】:2015-09-05 04:18:42
【问题描述】:

编辑:我解决了。在下面的答案中查看我的修复。

我正在开发一个应用程序,它应该在连接到运行它的计算机的每个屏幕上打开一个小弹出窗口。在单个屏幕上执行非常简单(使用 WindowStartupLocation = CenterScreen),但在多个屏幕上执行却异常困难。

我当前的代码是这样的:

        foreach (var s in Screen.AllScreens) //System.Windows.Forms.Screen
        {
            var b = s.Bounds;
            var w = new PopupWindow();

            var oW = w.Width; //Keep track of original size ...
            var oH = w.Height;

            w.Width = 0; //then set the size to 0, to avoid that the 
            w.Height = 0;//popup shows before it is correctly positioned

            w.Show(); //Now show it, so that we can place it (when I
                      //tried to place it before showing, the window
                      //was always repositioned when Show() was called)

            double dpiX = 1, dpiY = 1;
            var presentationsource = PresentationSource.FromVisual(w);

            if (presentationsource != null)
            {
                dpiX = presentationsource.CompositionTarget.TransformToDevice.M11;
                dpiY = presentationsource.CompositionTarget.TransformToDevice.M22;
            }

            var aW = oW*dpiX; //Calculate the actual size of the window
            var aH = oH*dpiY;

            //***** THIS IS WRONG, SEE ANSWER *****
            w.Left = (b.X + (b.Width / dpiX - aW) / 2); //Place it
            w.Top = (b.Y + (b.Height / dpiY - aH) / 2);
            //*************************************

            w.Width = oW; //And set the size back to the original size
            w.Height = oH;
        }

这似乎只在主屏幕上有效。在其他屏幕上,窗口未正确居中。

我想这是因为我对 WPF 和 DPI 的了解非常有限,而且我可能做错了什么。有人能指出我正确的方向吗?

【问题讨论】:

  • 您不应该使用代码手动将Popup 居中。您应该简单地使用Popup 类的PlacementTargetPlacement 属性。
  • 对不起,我可能不清楚;它实际上不是“Popup”类。我正在使用“Window”(如代码所示)。此外,问题不是集中在“一个”屏幕上,而是集中在多个屏幕上。所以这实际上不是链接问题的重复。 :)
  • 好的,我重新打开了这个问题。

标签: c# wpf centering multiple-monitors


【解决方案1】:

当然,我在这里发布后设法解决了它。当我试图用 DPI 划分整个位置时,看起来我做错了,这导致我走错了我在上面发布的路径。

放置表单的正确行应该是这样的(所有其他代码都可以):

                w.Left = (b.X + (b.Width - aW) / 2) / dpiX;
                w.Top = (b.Y + (b.Height - aH) / 2) / dpiX;

但是,我仍然认为这是一个简单任务的大量代码,所以如果有人有更好的想法,请告诉我!

所以这是我现在使用的(工作)代码:

    foreach (var s in Screen.AllScreens) //System.Windows.Forms.Screen
    {
        var b = s.Bounds;
        var w = new PopupWindow();

        var oW = w.Width; //Keep track of original size ...
        var oH = w.Height;

        w.Width = 0; //then set the size to 0, to avoid that the 
        w.Height = 0;//popup shows before it is correctly positioned

        w.Show(); //Now show it, so that we can place it (when I
                  //tried to place it before showing, the window
                  //was always repositioned when Show() was called)

        double dpiX = 1, dpiY = 1;
        var ps = PresentationSource.FromVisual(w);
        if (ps != null)
        {
            dpiX = ps.CompositionTarget.TransformToDevice.M11;
            dpiY = ps.CompositionTarget.TransformToDevice.M22;
        }

        var aW = oW*dpiX; //Calculate the actual size of the window
        var aH = oH*dpiY;

        w.Left = (b.X + (b.Width - aW) / 2) / dpiX;
        w.Top = (b.Y + (b.Height - aH) / 2) / dpiX;

        w.Width = oW; //And set the size back to the original size
        w.Height = oH;
    }

【讨论】:

    【解决方案2】:
            var centers =
                System.Windows.Forms.Screen.AllScreens.Select(
                    s =>
                        new
                        {
                            Left = s.Bounds.X + (s.WorkingArea.Right - s.WorkingArea.Left)/2,
                            Top = s.Bounds.Y + (s.WorkingArea.Bottom - s.WorkingArea.Top)/2
                        });
    
            foreach (var c in centers)
            {
                var w = new Window1();
    
                w.Left = c.Left - w.Width/2;
                w.Top = c.Top - w.Height/2;
    
                w.Show();
            }
    

    【讨论】:

    • 不,抱歉,这行不通。请参阅下面的答案以获取有效的解决方案。正如我试图在我的问题中解释的那样(我显然需要提高我的演讲技巧!:P),问题有两个方面:1)由于 DPI 和密度独立像素,在 WPF 中居中并不直接。您的示例适用于 Windows 窗体应用程序,但不适用于 WPF 应用程序。 2)代码变得复杂,因为我在放置表单后无法调用 Show()(运行代码时,所有表单都在主屏幕上打开,因为 Show() 在设置后会更改位置)。
    猜你喜欢
    • 1970-01-01
    • 2012-11-17
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-09-08
    • 2011-12-24
    相关资源
    最近更新 更多