Windows
C#
Xaml
フォーム

2台目のモニタにフォームを表示する

PCに接続した2台目のモニタにWindowsフォームを表示する。

PCに2台のモニタを接続してある。1台は通常のPCモニタで、2台目は大型のモニタで天井に吊るしてある。今回はWindowsフォームアプリで工場の生産状態を大型モニタに表示する(俗に言うあんどん)。
表示を2台目に固定することにより、1台目のモニタを使って、並行で他の作業ができるようになる。PCを有効に活用できるため、工場の人はうれしいわけです。

Form1.cs
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
            // あんどん表示を第2モニタに表示し、このフォームは閉じる
            var andon = new Form2();
            foreach (var scr in System.Windows.Forms.Screen.AllScreens)
            {
                if (!scr.Primary)
                {
                    andon.TopMost = true;
                    andon.Left = scr.Bounds.Left;
                    andon.Top = scr.Bounds.Top;
                    andon.Show();
                }
            }
            this.Close();
        }
    }

接続されているすべてのディスプレイを取得する。Primaryのものは第1モニタなので、除外する。Primaryでないものが第2モニタなので、こちらにあんどんのフォームを開いて表示する。呼び出した元のフォームは閉じる。
これで1台目には何も表示せず、2台目にはフォームを閉じない限り表示しっぱなしにできた。
xamlでも同じことができる。

Window1.xaml.cs
    public partial class Window1 : Window
    {
        public Window1()
        {
            InitializeComponent();
            // あんどん表示を第2モニタに表示し、このフォームは閉じる
            var andon = new Window2();
            foreach (var scr in System.Windows.Forms.Screen.AllScreens)
            {
                if (!scr.Primary)
                {
                    andon.Topmost = true;
                    andon.Left = scr.Bounds.Left;
                    andon.Top = scr.Bounds.Top;
                    andon.Show();
                    andon.WindowState = System.Windows.WindowState.Maximized;
                }
            }
            this.Close();
        }
    }

追記

WPFアプリで上記の内容をやろうとしたところ、うまくいかず常に一方のモニタへウィンドウが表示されてしまった。デバッグすると、andon.Leftには1300等がちゃんと入っているのに、Left = 0として表示されている。原因は、XamlでWindowState="Maximized"を指定していたこと。Xamlでは書かずに、Xaml.csでShow()した後に、ウィンドウ最大化を指定しなければならない。

Window2.xaml
<Window x:Class="OperationManager.Window2"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        Height="1024" Width="1280" ShowInTaskbar="True" ResizeMode="CanResizeWithGrip" WindowState="Maximized"
        >

上記のようになっていてはダメ。WindowState="Maximized"を消すこと!