如何在第二显示器上设置WPF窗口的位置

26

我有两个显示器。我想制作一个媒体播放器,我想在我的次要显示器上全屏播放视频。因此,我正在尝试使用WPF制作媒体播放器。

这是我到目前为止编写的代码:

Screen[] _screens = Screen.AllScreens;
System.Drawing.Rectangle ractagle = _screens[1].Bounds;
//player is  my window
player.WindowState = WindowState.Maximized;
player.WindowStyle = WindowStyle.None;

player.Left = ractagle.X;
player.Top = ractagle.Y;


// MediaControl is an media elements
MediaControl.Height = ractagle.Height;
MediaControl.Width = ractagle.Width;

但是不知何故它只在我的第一个显示器上播放。非常感谢任何形式的帮助。

5个回答

25

您需要确保正在显示的窗体的WindowStartupLocation设置为Manual

否则,您所做的任何事情都不会影响窗口的位置。

using System.Windows.Forms;
// reference System.Drawing
//

Screen s = Screen.AllScreens[1];

System.Drawing.Rectangle r  = s.WorkingArea;
Me.Top = r.Top;
Me.Left = r.Left;

我使用的 Window 的 XAML 头部。

<Window x:Class="MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="MainWindow" Height="350" Width="823" WindowStartupLocation="Manual">
    <Canvas Width="743">
        //Controls etc
    </Canvas>
</Window>

嘿,它不起作用了,我已经仔细检查过了,我将WindowStartupLocation设置为手动。 - A N M Bazlur Rahman
我写了一个小示例来演示,对我来说它可以工作。什么没有起作用?请参见我使用的XAML的编辑。 - Paul Farry
不错的解决方案。然而,它仅在第二个屏幕上提供了全屏窗口(仍可见窗口边框等)。如果其他人碰巧看到这篇文章并想要完整的全屏,则可以在此处找到解决方案:http://mostlytech.blogspot.de/2008/01/maximizing-wpf-window-to-second-monitor.html - Heribert

9

五年后!但对于像我一样偶然发现这篇文章的其他人...

如果您不能或不想添加整个System.Windows.Forms dll引用,您可以使用WpfScreenHelper(在NuGet中搜索)由micdenny编写的程序。

  Screen screen = WpfScreenHelper.AllScreens[0];
  Left = screen.Bounds.Left;
  Top = screen.Bounds.Top;
  Width = screen.Bounds.Width;
  Height = screen.Bounds.Height;

Micdenny已将Windows Forms屏幕助手移植到WPF平台。这对于那些与WPF引用不兼容的情况非常有用(比如WPF Live-Charts)。

1
对我来说不起作用,我必须更改代码才能编译它。(例如:Screen screen = Screen.AllScreens.ToList<Screen>()[0]; ...)。无论如何,将索引0更改为1没有效果。还需要其他东西才能使其工作吗?我安装了WpfScreenHelper的0.3.0(当前版本)。 - Exel Gamboa
1
@ExelGamboa 很抱歉你遇到了问题。在我的情况下,Nuget 安装正常。然后我建立了一个只使用 WpfScreenHelper 和通用集合的 ScreenManager 类。我有一个 "public List<Screen> Screens;",我在构造函数中填充它,使用 "Screens = new List<Screen>(Screen.AllScreens);"。然后我创建了一个方法 "public Screen GetScreen(int index){ return Screens[index]; }",我使用从返回的 "screen.Bounds" 填充的 Rect 来定位和调整 App 的大小。我完全没有遇到任何构建问题。你还安装/引用了什么?也许有冲突的地方? - Eclectic
也许是这样。感谢您提供的详细信息,我会再次尝试并检查是否有所不同。 - Exel Gamboa
如果次要显示器的比例或 DPI 与主显示器不同,这种方法可能会出现问题。但在相同的显示器上,这个方法运行得很完美。 - GrandMasterFlush

3

我的解决方案结合了这些想法,并确保辅助屏幕存在:

    using System.Linq;
    // ...
    public partial class MainWindow : Window
    {
        public MainWindow()
        {                
            InitializeComponent();

            var screens = System.Windows.Forms.Screen.AllScreens;
            var firstSecondary = screens.FirstOrDefault(s => s.Primary == false);
            if (firstSecondary != null)
            {
                WindowStartupLocation = WindowStartupLocation.Manual; 
                // Ensure Window is minimzed on creation
                WindowState = WindowState.Minimized; XAML
                // Define Position on Secondary screen, for "Normal" window-mode
                // ( Here Top/Left-Position )
                Left = firstSecondary.Bounds.Left;
                Top = firstSecondary.Bounds.Top;
            }            
            Loaded += MainWindow_Loaded;
        }    

        private void MainWindow_Loaded(object sender, RoutedEventArgs e)
        {
            // Maximize after position is defined in constructor
            WindowState = WindowState.Maximized;    
        }
     }

这个解决方案对我来说非常有效,谢谢! - treterelda

3

我在 VS 2019 中使用以下内容:

private void MaximizeToSecondaryScreen()
{
    this.Left = SystemParameters.VirtualScreenLeft;
    this.Top = SystemParameters.VirtualScreenTop;
    this.Height = SystemParameters.VirtualScreenHeight;
    this.Width = SystemParameters.VirtualScreenWidth;
}

这是有用的知识,先前关于这个主题的一些答案在额外的显示器尺寸和不同的 DPI / 缩放因子下可能无法正常工作。 - GrandMasterFlush
这对我有用,但如果您的屏幕具有不同的刷新率,它将导致画布滞后。 - user21139719

2

如果你立即将窗口设置为最大化,它将无法正常工作。 使用已加载的事件,您不需要Windows窗体。

var secondaryScreenLeft = SystemParameters.PrimaryScreenWidth - SystemParameters.VirtualScreenWidth;

window.WindowStartupLocation = WindowStartupLocation.Manual;
window.Left = secondaryScreenLeft ;
window.Top = 0;
window.Loaded += Window_Loaded;

private void Window_Loaded(object sender, RoutedEventArgs e)
{
    var senderWindow = sender as Window;
    senderWindow.WindowState = WindowState.Maximized;
}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接