WPF ウィンドウの概要 (WPF .NET)

ユーザーは、ウィンドウを通じて Windows Presentation Foundation (WPF) アプリケーションと対話します。 ウィンドウの主な目的は、データを視覚化してユーザーがデータと対話できるコンテンツをホストすることです。 WPF アプリケーションには、Window クラスを使用した独自のウィンドウがあります。 この記事では、Window について説明してから、アプリケーションにおけるウィンドウの作成と管理の基本について説明します。

重要

この記事では、C# プロジェクトから生成された XAML を使用します。 Visual Basic を使用している場合、XAML の外観は少し異なる場合があります。 これらの違いは、通常、x:Class 属性値にあります。 C# には、プロジェクトのルート名前空間が含まれていますが、Visual Basic にはありません。

C# のプロジェクト テンプレートでは、app.xaml ファイルに格納されている App 型が作成されます。 Visual Basic では、型は Application という名前で、ファイルには Application.xaml という名前が付けられます。

ウィンドウ クラス

WPF では、ウィンドウは Window クラスでカプセル化され、これを使用して以下の操作を実行できます。

  • ウィンドウを表示する。
  • ウィンドウのサイズ、位置、および外観を構成する。
  • アプリケーション固有のコンテンツをホストする。
  • ウィンドウの有効期間を管理する。

次の図は、ウィンドウの構成パーツを示しています。

WPF ウィンドウのパーツを示すスクリーンショット。

ウィンドウは、非クライアント領域とクライアント領域の 2 つに分かれます。

ウィンドウの "非クライアント領域" は、WPF によって実装され、多くのウィンドウに共通のウィンドウのパーツが含まれます。これらのパーツには次のものがあります。

  • タイトル バー (1-5)。
  • アイコン (1)。
  • タイトル (2)。
  • 最小化 (3)、最大化 (4)、および閉じる (5) ボタン。
  • メニュー項目を含むシステム メニュー (6)。 アイコン (1) をクリックすると表示されます。
  • 境界線 (7)。

ウィンドウの "クライアント領域" は、ウィンドウの非クライアント領域の内側の領域であり、開発者がメニュー バー、ツール バー、コントロールなどのアプリケーション固有のコンテンツを追加するために使用します。

  • クライアント領域 (8)。
  • グリップのサイズ変更 (9)。 これは、クライアント領域 (8) に追加されたコントロールです。

ウィンドウの実装

一般的なウィンドウの実装には、外観と動作が含まれます。"外観" では、ユーザーに対するウィンドウの表示方法が定義されます。"動作" では、ユーザーがウィンドウと対話するときの動作が定義されます。 WPF では、コードまたは XAML マークアップを使用して、ウィンドウの外観と動作を実装できます。

ただし、通常は、次の例に示すように、XAML マークアップを使用してウィンドウの外観を実装して、コードビハインドを使用してその動作を実装します。

<Window x:Class="WindowsOverview.Window1"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
        xmlns:local="clr-namespace:WindowsOverview"
        >

    <!-- Client area containing the content of the window -->
    
</Window>

次のコードは、XAML のコードビハインドです。

using System.Windows;

namespace WindowsOverview
{
    public partial class Window1 : Window
    {
        public Window1()
        {
            InitializeComponent();
        }
    }
}
Public Class Window1

End Class

XAML マークアップ ファイルとコードビハインド ファイルを連携させるには、次のことが必要です。

  • マークアップでは、Window 要素に x:Class 属性を含める必要があります。 アプリケーションのビルド時に x:Class 属性が含まれていると、Microsoft Build Engine (MSBuild) により、x:Class 属性で指定された名前を持つ、Window から派生した partial クラスが生成されます。 そのためには、XAML スキーマ (xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml") に XML 名前空間宣言を追加する必要があります。 生成された partial クラスでは InitializeComponent メソッドが実装されます。このメソッドを呼び出すとイベントが登録され、マークアップで実装されるプロパティが設定されます。

  • 分離コードでは、クラスは、マークアップ内の x:Class 属性で指定されている名前を持つ partial クラスでなければなりません。また、Window から派生する必要があります。 これによって、コードビハインド ファイルと、アプリケーションのビルド時にマークアップ ファイル用に生成される partial クラスとが関連付けられます (「WPF アプリケーションをコンパイルする」を参照)。

  • 分離コードでは、Window クラスによって実装されるコンストラクターで InitializeComponent メソッドが呼び出される必要があります。 InitializeComponent は、マークアップ ファイル用に生成された partial クラスによって実装されるもので、イベントの登録と、マークアップで定義されたプロパティの設定を実行します。

注意

Visual Studio を使用してプロジェクトに新しい Window を追加すると、ここで説明したように、マークアップと分離コードの両方を使用して Window が実装され、マークアップ ファイルと分離コード ファイル間の関連付けの作成に必要な構成が組み込まれます。

この構成が組み込まれると、XAML マークアップ内でウィンドウの外観を定義し、コードビハインド内でその動作を実装することに集中できます。 次の例では、Click イベントのイベント ハンドラーを定義するボタンがウィンドウに表示されています。 これは XAML で実装され、ハンドラーはコードビハインドで実装されます。

<Window x:Class="WindowsOverview.Window1"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
        xmlns:local="clr-namespace:WindowsOverview"
        >

    <!-- Client area containing the content of the window -->

    <Button Click="Button_Click">Click This Button</Button>
    
</Window>

次のコードは、XAML のコードビハインドです。

using System.Windows;

namespace WindowsOverview
{
    public partial class Window1 : Window
    {
        public Window1()
        {
            InitializeComponent();
        }

        private void Button_Click(object sender, RoutedEventArgs e)
        {
            MessageBox.Show("Button was clicked.");
        }
    }
}
Public Class Window1

    Private Sub Button_Click(sender As Object, e As RoutedEventArgs)
        MessageBox.Show("Button was clicked.")
    End Sub

End Class

MSBuild 用のウィンドウの構成

ウィンドウを実装する方法によって、MSBuild での構成方法が決定されます。 XAML マークアップとコードビハインドの両方を使用して定義したウィンドウの場合:

  • XAML マークアップ ファイルは、MSBuild Page 項目として構成する必要があります。
  • 分離コード ファイルは、MSBuild Compile 項目として構成されます。

.NET SDK プロジェクトでは、適切な PageCompile の項目が自動的にインポートされるため、これらを宣言する必要はありません。 プロジェクトが WPF 用に構成されている場合、XAML マークアップ ファイルは Page 項目として自動的にインポートされ、対応するコードビハインド ファイルは Compile としてインポートされます。

MSBuild プロジェクトでは、型が自動的にインポートされないため、自分で宣言する必要があります。

<Project>
    ...
    <Page Include="MarkupAndCodeBehindWindow.xaml" />
    <Compile Include=" MarkupAndCodeBehindWindow.xaml.cs" />
    ...
</Project>

WPF アプリケーションのビルドの詳細については、「WPF アプリケーションをコンパイルする」を参照してください。

ウィンドウの有効期間

クラスと同様に、ウィンドウにも有効期間があります。これは、ウィンドウが開いて最初にインスタンス化されたときに開始し、アクティブ化または非アクティブ化を経て、最後に閉じられるまで継続します。

ウィンドウを開く

ウィンドウを開くには、次の例に示すように最初にインスタンスを作成します。

using System.Windows;

namespace WindowsOverview
{
    public partial class App : Application
    {
        private void Application_Startup(object sender, StartupEventArgs e)
        {
            // Create the window
            Window1 window = new Window1();

            // Open the window
            window.Show();
        }
    }
}
Class Application

    Private Sub Application_Startup(sender As Object, e As StartupEventArgs)
        ' Create the window
        Dim window As New Window1

        ' Open the window
        window.Show()
    End Sub

End Class

この例では、Startup イベントが発生してアプリケーションが開始するときに Window1 がインスタンス化されます。 スタートアップ ウィンドウの詳細については、「メイン アプリケーション ウィンドウを取得または設定する方法」を参照してください。

ウィンドウがインスタンス化されると、Application オブジェクトによって管理されるウィンドウのリストにその参照が自動的に追加されます。 インスタンス化される最初のウィンドウは、Application によってメイン アプリケーション ウィンドウとして自動的に設定されます。

最後に、Show メソッドを呼び出すことによって次の画像のようなウィンドウが開きます。

Show を呼び出すことで開くウィンドウは、"モードレス" ウィンドウであり、ユーザーがアプリケーションで、アプリケーション内の他のウィンドウと対話することができます。 ShowDialog でウィンドウを開くと、"モーダル" としてウィンドウが開き、ユーザーの操作が特定のウィンドウに制限されます。 詳細については、「ダイアログ ボックスの概要」を参照してください。

Show を呼び出すと、ウィンドウが表示される前に初期化処理が実行され、ユーザーの入力を受け取ることのできるインフラストラクチャが確立されます。 ウィンドウが初期化されると、SourceInitialized イベントが発生し、ウィンドウが表示されます。

詳細については、「ウィンドウまたはダイアログ ボックスを開く方法」を参照してください。

スタートアップ ウィンドウ

前の例では、Startup イベントを使用して、最初のアプリケーション ウィンドウを表示するコードを実行しました。 ショートカットとして、代わりに StartupUri を使用して、アプリケーション内の XAML ファイルへのパスを指定します。 アプリケーションは、そのプロパティによって指定されたウィンドウを自動的に作成して表示します。

<Application x:Class="WindowsOverview.App"
             xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
             xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
             xmlns:local="clr-namespace:WindowsOverview"
             StartupUri="ClippedWindow.xaml">
    <Application.Resources>
         
    </Application.Resources>
</Application>

ウィンドウの所有権

Show メソッドを使用して開いたウィンドウには、それを作成したウィンドウとの暗黙的な関係はありません。 ユーザーは一方のウィンドウを独立して操作できるため、どちらかのウィンドウで次が実行できることになります。

  • もう一方の上に表示する (いずれかのウィンドウの Topmost プロパティが true に設定されている場合を除く)。
  • もう一方のウィンドウに影響を与えずに、最小化/最大化し、元のサイズに戻す。

一部のウィンドウには、そのウィンドウを開いたウィンドウとの関係が必要です。 たとえば、統合開発環境 (IDE) アプリケーションでは、プロパティ ウィンドウやツール ウィンドウのように、一般的に作成元のウィンドウの上に表示されるウィンドウが開く場合があります。 また、そのようなウィンドウは、必ず作成元のウィンドウと一緒に閉じ、最小化/最大化し、元のサイズに戻す必要があります。 このような関係を確立するには、あるウィンドウが別のウィンドウを "所有" するようにします。そのためには、"所有されているウィンドウ" の Owner プロパティに、"オーナー ウィンドウ" への参照を設定します。 これを次の例に示します。

private void Button_Click(object sender, RoutedEventArgs e)
{
    // Create a window and make the current window its owner
    var ownedWindow = new ChildWindow1();
    ownedWindow.Owner = this;
    ownedWindow.Show();
}
Private Sub Button_Click(sender As Object, e As RoutedEventArgs)
    ' Create a window and make the current window its owner
    Dim ownedWindow As New ChildWindow1
    ownedWindow.Owner = Me
    ownedWindow.Show()
End Sub

所有権が確立されると、次のようになります。

  • 所有されているウィンドウでは、Owner プロパティの値を検査することによってオーナー ウィンドウを参照できます。
  • オーナー ウィンドウでは、OwnedWindows プロパティの値を検査することによって、所有するすべてのウィンドウを検出できます。

ウィンドウのアクティブ化

ウィンドウを最初に開いたときは、そのウィンドウがアクティブ ウィンドウになります。 "アクティブ ウィンドウ" は、キー ストロークやマウス クリックなどのユーザー入力を現在キャプチャしているウィンドウです。 ウィンドウがアクティブになると、Activated イベントが発生します。

注意

ウィンドウが最初に開かれるとき、Loaded イベントと ContentRendered イベントは、Activated イベントが発生した後にのみ発生します。 そのため、事実上、ウィンドウは ContentRendered が発生した場合にのみ開いたと見なすことができます。

ウィンドウがアクティブになった後で、ユーザーは同じアプリケーションの別のウィンドウをアクティブ化したり、別のアプリケーションをアクティブ化したりできます。 このとき、現在アクティブなウィンドウが非アクティブ化され、Deactivated イベントが発生します。 同様に、ユーザーが現在非アクティブなウィンドウを選択すると、ウィンドウは再びアクティブになり、Activated が発生します。

一般に、ActivatedDeactivated を処理するのは、ウィンドウがアクティブなときにのみ実行できる機能を有効または無効にするためです。 たとえば、ゲームやビデオ プレーヤーなど、ユーザーの一定の入力や介入が必要な対話型コンテンツが表示されるウィンドウがあります。 この動作を実装するために ActivatedDeactivated を処理する方法を、次の簡単なビデオ プレーヤーの例で示します。

<Window x:Class="WindowsOverview.CustomMediaPlayerWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        Activated="Window_Activated"
        Deactivated="Window_Deactivated"
        Title="CustomMediaPlayerWindow" Height="450" Width="800">
    <Grid>
        <MediaElement x:Name="mediaElement" Stretch="Fill"
                      LoadedBehavior="Manual" Source="numbers.mp4" />
    </Grid>
</Window>

次のコードは、XAML のコードビハインドです。

using System;
using System.Windows;

namespace WindowsOverview
{
    public partial class CustomMediaPlayerWindow : Window
    {
        public CustomMediaPlayerWindow() =>
            InitializeComponent();

        private void Window_Activated(object sender, EventArgs e)
        {
            // Continue playing media if window is activated
            mediaElement.Play();
        }

        private void Window_Deactivated(object sender, EventArgs e)
        {
            // Pause playing if media is being played and window is deactivated
            mediaElement.Pause();
        }
    }
}
Public Class CustomMediaPlayerWindow
    Private Sub Window_Activated(sender As Object, e As EventArgs)
        ' Continue playing media if window Is activated
        mediaElement.Play()
    End Sub

    Private Sub Window_Deactivated(sender As Object, e As EventArgs)
        ' Pause playing if media is being played and window is deactivated
        mediaElement.Pause()
    End Sub
End Class

ウィンドウが非アクティブでも、バックグラウンドでコードを実行できる種類のアプリケーションもあります。 たとえば、メール クライアントは、ユーザーが他のアプリケーションを使用している間もメール サーバーへのポーリングを続けています。 このようなアプリケーションは、メイン ウィンドウが非アクティブのときにも、別の、または追加の動作を頻繁に実行します。 これによって、メール プログラムが、新しいメール アイテムを受信トレイに追加し、通知アイコンをシステム トレイに追加することがあります。 通知アイコンは、メール ウィンドウがアクティブでないときにのみ表示する必要があります。これは、IsActive プロパティを検査することで確認できます。

バックグラウンド タスクの完了時に、ユーザーに緊急に通知する必要がある場合は、Activate メソッドを呼び出します。 Activate を呼び出したときに、ユーザーが別のアクティブなアプリケーションと対話している場合は、ウィンドウのタスク バー ボタンが点滅します。 ただし、ユーザーが現在のアプリケーションと対話している場合は、Activate を呼び出すと、ウィンドウが前面に表示されます。

Note

Application.Activated イベントと Application.Deactivated イベントを使用して、アプリケーションスコープのアクティベーションを処理できます。

ウィンドウのアクティブ化の防止

表示されてもアクティブにすべきでないウィンドウもあります。チャット アプリケーションのような会話ウィンドウや、電子メール アプリケーションの通知ウィンドウなどです。

表示されるときにアクティブにしないウィンドウがアプリケーションにある場合は、Show メソッドの初回呼び出し前に、ShowActivated プロパティを false に設定します。 結果は次のようになります。

  • ウィンドウがアクティブ化されません。
  • ウィンドウの Activated イベントは発生しません。
  • 現在アクティブなウィンドウは、アクティブのままです。

ただし、ユーザーがクライアント領域または非クライアント領域をクリックすると、ウィンドウは直ちにアクティブになります。 この場合、次のようになります。

  • ウィンドウはアクティブになります。
  • ウィンドウの Activated イベントが発生します。
  • 直前にアクティブだったウィンドウは非アクティブになります。
  • ウィンドウの DeactivatedActivated のイベントが、ユーザーの操作への応答として想定どおりに発生します。

ウィンドウを閉じる

ウィンドウの有効期間は、表示されたときに開始し、ユーザーが閉じたときに終了します。 いったん閉じたウィンドウを、再び開くことはできません。 ウィンドウを閉じるには、非クライアント領域の要素を使用します。これには、次のものが含まれます。

  • [システム] メニューの [閉じる] 項目。
  • Alt + F4 キーを押す。
  • [閉じる] ボタンを押す。
  • モーダル ウィンドウで、ボタンの IsCancel プロパティが true に設定されている場合に ESC キーを押す。

クライアント領域にウィンドウを閉じるための機構をさらに追加することもできます。その一般的な例を、次に示します。

  • 一般にメイン アプリケーション ウィンドウにある、 [ファイル] メニューの [終了] 項目。
  • 一般にアプリケーションの 2 次ウィンドウにある、 [ファイル] メニューの [閉じる] 項目。
  • 一般にモーダル ダイアログ ボックスにある [キャンセル] ボタン。
  • 一般にモードレス ダイアログ ボックスにある [閉じる] ボタン。

これらのカスタム機構のいずれかに対応してウィンドウを閉じるには、Close メソッドを呼び出す必要があります。 [ファイル] メニューの [終了] をクリックすることでウィンドウを閉じる機能を実装する方法を、次の例に示します。

<Window x:Class="WindowsOverview.ClosingWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        Title="ClosingWindow" Height="450" Width="800">
    <StackPanel>
        <Menu>
            <MenuItem Header="_File">
                <MenuItem Header="E_xit" Click="fileExitMenuItem_Click" />
            </MenuItem>
        </Menu>
    </StackPanel>
</Window>

次のコードは、XAML のコードビハインドです。

using System.Windows;

namespace WindowsOverview
{
    public partial class ClosingWindow : Window
    {
        public ClosingWindow() =>
            InitializeComponent();

        private void fileExitMenuItem_Click(object sender, RoutedEventArgs e)
        {
            // Close the current window
            this.Close();
        }
    }
}
Public Class ClosingWindow
    Private Sub fileExitMenuItem_Click(sender As Object, e As RoutedEventArgs)
        ' Close the current window
        Me.Close()
    End Sub
End Class

Note

メイン アプリケーション ウィンドウを閉じるか、最後のウィンドウを閉じるときに、アプリケーションが自動的にシャットダウンされるように構成することができます (「MainWindow」を参照)。 詳細については、ShutdownModeを参照してください。

非クライアント領域およびクライアント領域に提供される機構によって、ウィンドウを明示的に閉じることができます。また、次のような場合に、アプリケーションまたは Windows の他の部分の動作の結果として、ウィンドウを暗黙的に閉じることもできます。

  • ユーザーが Windows からログオフしたか、Windows をシャットダウンした場合。
  • ウィンドウの Owner が閉じる。
  • メイン アプリケーション ウィンドウが閉じられ、ShutdownModeOnMainWindowClose である場合。
  • Shutdown が呼ばれたとき。

重要

ウィンドウを閉じると、再度開くことはできません。

ウィンドウの終了を取り消す

ウィンドウが閉じるとき、ClosingClosed の 2 つのイベントが発生します。

Closing はウィンドウが閉じる前に発生し、ウィンドウが閉じるのを防ぐことができる機構を提供します。 ウィンドウが閉じるのを防ぐのは、一般的に、ウィンドウ コンテンツに変更したデータが含まれている場合です。 この場合、Closing イベントを処理して、データが変更されているかどうかを確認できます。変更されている場合は、ユーザーにデータを保存しないでこのままウィンドウを閉じるか、またはウィンドウを閉じる操作を取り消すかを確認できます。 Closing を処理するときの要点を、次の例に示します。

<Window x:Class="WindowsOverview.DataWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        Title="DataWindow" Height="450" Width="800"
        Closing="Window_Closing">
    <Grid>
        <TextBox x:Name="documentTextBox" TextChanged="documentTextBox_TextChanged" />
    </Grid>
</Window>

次のコードは、XAML のコードビハインドです。

using System.Windows;
using System.Windows.Controls;

namespace WindowsOverview
{
    public partial class DataWindow : Window
    {
        private bool _isDataDirty;

        public DataWindow() =>
            InitializeComponent();

        private void documentTextBox_TextChanged(object sender, TextChangedEventArgs e) =>
            _isDataDirty = true;

        private void Window_Closing(object sender, System.ComponentModel.CancelEventArgs e)
        {
            // If data is dirty, prompt user and ask for a response
            if (_isDataDirty)
            {
                var result = MessageBox.Show("Document has changed. Close without saving?",
                                             "Question",
                                             MessageBoxButton.YesNo);

                // User doesn't want to close, cancel closure
                if (result == MessageBoxResult.No)
                    e.Cancel = true;
            }
        }
    }
}
Public Class DataWindow

    Private _isDataDirty As Boolean

    Private Sub documentTextBox_TextChanged(sender As Object, e As TextChangedEventArgs)
        _isDataDirty = True
    End Sub

    Private Sub Window_Closing(sender As Object, e As ComponentModel.CancelEventArgs)

        ' If data is dirty, prompt user and ask for a response
        If _isDataDirty Then
            Dim result = MessageBox.Show("Document has changed. Close without saving?",
                                         "Question",
                                         MessageBoxButton.YesNo)

            ' User doesn't want to close, cancel closure
            If result = MessageBoxResult.No Then
                e.Cancel = True
            End If
        End If

    End Sub
End Class

Closing イベント ハンドラーに CancelEventArgs が渡されます。これにより、ウィンドウが閉じるのを防ぐために true に設定する Cancel プロパティが実装されます。

Closing が処理されない場合、または処理されたがキャンセルされていない場合、ウィンドウは閉じられます。 ウィンドウが実際に閉じられる直前に、Closed が発生します。 この時点で、ウィンドウが閉じるのを防ぐことはできません。

ウィンドウの有効期間イベント

次の図は、ウィンドウの有効期間内における主要なイベントのシーケンスを示しています。

ウィンドウの有効期間内のイベントを示す図。

次の図は、アクティブ化しないで表示されるウィンドウの有効期間内における主要なイベントのシーケンスを示しています (ウィンドウが表示される前に ShowActivatedfalse に設定されています)。

アクティブ化なしでのウィンドウの有効期間内のイベントを示す図。

ウィンドウの位置

ウィンドウが開いているとき、ウィンドウはデスクトップに対して相対的な x ディメンションと y ディメンションの位置にあります。 この位置は、Left プロパティと Top プロパティをそれぞれ検査することで確認できます。 これらのプロパティを設定して、ウィンドウの位置を変更します。

WindowStartupLocation プロパティを次の WindowStartupLocation 列挙値のいずれかに設定して、Window が最初に表示されるときの初期位置を指定することもできます。

開始位置が Manual と指定され、LeftTop のプロパティが設定されていない場合、Window が、オペレーティング システムに表示位置を問い合わせます。

最上位ウィンドウと z オーダー

ウィンドウには、x 位置と y 位置に加えて、他のウィンドウを基準にして垂直位置を決定する z ディメンションの位置もあります。 これはウィンドウの z オーダーともいい、標準 z オーダーと最上位 z オーダーの 2 種類があります。 "標準 z オーダー" にあるウィンドウの位置は、それが現在アクティブかどうかによって決まります。 既定では、ウィンドウは標準 z オーダーにあります。 "最上位 z オーダー" にあるウィンドウの位置も、それが現在アクティブかどうかによって決まります。 また、最上位 z オーダーにあるウィンドウは、常に、標準 z オーダーにあるウィンドウの上に位置します。 ウィンドウを最上位 z オーダーに配置するには、ウィンドウの Topmost プロパティを true に設定します。

各 z オーダー タイプ内で、現在アクティブなウィンドウは、同じ z オーダーにある他のすべてのウィンドウの上に表示されます。

ウィンドウ サイズ

ウィンドウには、デスクトップの位置に加えて、さまざまな幅と高さのプロパティや SizeToContent など、複数のプロパティによって決定されるサイズがあります。

MinWidthWidth、および MaxWidth を使用して、有効期間中にウィンドウに指定できる幅の範囲を管理します。

<Window 
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    MinWidth="300" Width="400" MaxWidth="500">
</Window>

ウィンドウの高さは、MinHeightHeight、および MaxHeight によって管理されます。

<Window 
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    MinHeight="300" Height="400" MaxHeight="500">
</Window>

さまざまな幅の値と高さの値はそれぞれ範囲を指定しているため、サイズを変更できるウィンドウの幅と高さは、それぞれの寸法に指定された範囲内のいずれかの値を取ります。 現在の幅と高さを検出するには、それぞれ ActualWidthActualHeight を検査します。

ウィンドウの幅と高さを、ウィンドウのコンテンツのサイズに合わせたサイズにする場合は、SizeToContent プロパティを使用できます。これは、次の値を取ります。

次の例では、ウィンドウを最初に表示するときに、そのコンテンツに合わせて垂直方向と水平方向の両方のサイズを自動的に変更するウィンドウを示しています。

<Window 
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
    SizeToContent="WidthAndHeight">
</Window>

次の例では、ウィンドウをそのコンテンツに合わせてサイズ変更する方法を指定するために、コード内に SizeToContent プロパティを設定する方法を示します。

// Manually alter window height and width
this.SizeToContent = SizeToContent.Manual;

// Automatically resize width relative to content
this.SizeToContent = SizeToContent.Width;

// Automatically resize height relative to content
this.SizeToContent = SizeToContent.Height;

// Automatically resize height and width relative to content
this.SizeToContent = SizeToContent.WidthAndHeight;
' Manually alter window height and width
Me.SizeToContent = SizeToContent.Manual

' Automatically resize width relative to content
Me.SizeToContent = SizeToContent.Width

' Automatically resize height relative to content
Me.SizeToContent = SizeToContent.Height

' Automatically resize height and width relative to content
Me.SizeToContent = SizeToContent.WidthAndHeight

サイズ変更プロパティの優先順位

基本的に、ウィンドウのさまざまなサイズのプロパティを組み合わせて、サイズを変更できるウィンドウの幅と高さの範囲を定義します。 有効な範囲が維持されていることを確認するために、Window では次の優先順位でサイズ プロパティの値が評価されます。

高さのプロパティ:

  1. FrameworkElement.MinHeight
  2. FrameworkElement.MaxHeight
  3. SizeToContent.Height / SizeToContent.WidthAndHeight
  4. FrameworkElement.Height

幅のプロパティ:

  1. FrameworkElement.MinWidth
  2. FrameworkElement.MaxWidth
  3. SizeToContent.Width / SizeToContent.WidthAndHeight
  4. FrameworkElement.Width

優先順位では、ウィンドウが最大化されたときのサイズも決定されます。これは、WindowState プロパティで管理します。

Window state

サイズを変更できるウィンドウには、有効期間中、通常、最小化、最大化の 3 つの状態があります。 "通常" の状態のウィンドウは、ウィンドウの既定の状態です。 この状態のウィンドウは、サイズ変更グリップ、またはサイズ変更可能な場合は境界線を使用して、ユーザーが移動したりサイズ変更したりできます。

"最小化" された状態のウィンドウは、ShowInTaskbartrue に設定されている場合は、折りたたまれてタスク バー ボタンになります。それ以外の場合は、折りたたまれて、可能な最小のサイズになり、デスクトップの左下隅に自動的に移動します。 最小化されたウィンドウはいずれの種類も、境界線またはサイズ変更グリップを使用してサイズ変更できません。ただし、タスク バーに表示されていない最小化されたウィンドウはデスクトップの任意の場所にドラッグできます。

"最大化" された状態のウィンドウは、拡大されて、可能な最大のサイズになります。これは、MaxWidth プロパティ、MaxHeight プロパティ、および SizeToContent プロパティが指定するのと同じサイズです。 最小化されたウィンドウと同様、最大化されたウィンドウは、サイズ変更グリップを使用したり、境界線をドラッグしたりすることによってサイズ変更できません。

Note

ウィンドウが現在最大化または最小化されている場合でも、ウィンドウの TopLeftWidth、および Height の各プロパティの値は、通常の状態の値を常に表します。

ウィンドウの状態は、WindowState プロパティを設定することによって構成できます。これは、次の WindowState 列挙値のいずれかを取ります。

開くときに最大化されて表示されるウィンドウを作成する方法を、次の例に示します。

<Window 
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    WindowState="Maximized">
</Window>

通常は、WindowState を設定してウィンドウの初期状態を構成する必要があります。 "サイズ変更可能な" ウィンドウが表示されると、ユーザーはウィンドウのタイトル バーにある最小化、最大化、および元に戻すのボタンを使用して、ウィンドウの状態を変更できます。

ウィンドウの外観

ウィンドウのクライアント領域の外観を変更するために、ボタン、ラベル、テキスト ボックスなど、ウィンドウ固有のコンテンツを追加します。 非クライアント領域を構成するために、Window には、ウィンドウのアイコンを設定する Icon、タイトルを設定する Title など、いくつかのプロパティが用意されています。

また、ウィンドウのサイズ変更モード、ウィンドウ スタイル、デスクトップのタスク バーにボタンとして表示するかどうかを構成して、非クライアント領域の境界線の外観と動作も変更できます。

サイズ変更モード

WindowStyle プロパティに応じて、ユーザーがウィンドウのサイズを変更するかどうかと、その方法を制御できます。 ウィンドウ スタイルは、次に影響します。

  • ウィンドウの境界線をマウスでドラッグすることによるサイズ変更を、許可または禁止する。
  • [最小化][最大化][閉じる] の各ボタンを非クライアント領域に表示するかどうか。
  • [最小化][最大化][閉じる] の各ボタンが有効になっているかどうか。

ウィンドウのサイズ変更方法は、ResizeMode プロパティを設定することによって構成できます。これは、次の ResizeMode 列挙値のいずれかを取ります。

WindowStyle と同様に、ウィンドウのサイズ変更モードは、有効期間中に変更される可能性はほとんどありません。したがって、多くの場合は XAML マークアップから設定します。

<Window 
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    ResizeMode="CanResizeWithGrip">
</Window>

WindowState プロパティを検査することによって、ウィンドウが最大化されているか、最小化されているか、元のサイズに戻されているかを検出できることに注意してください。

Window style

ウィンドウの非クライアント領域から公開される境界線は、多くのアプリケーションに適しています。 ただし、ウィンドウの種類によって、異なる種類の境界線が必要な状況や、境界線がまったく必要ない状況があります。

ウィンドウの境界線の種類を制御するには、WindowStyle プロパティを次の WindowStyle 列挙値のいずれかに設定します。

ウィンドウ スタイルを適用した場合の効果を次の画像に示します。

ウィンドウ スタイルが WPF のウィンドウに与える影響を示すスクリーンショット。

上の画像では、SingleBorderWindowThreeDBorderWindow の間に顕著な違いが示されていないことに注目してください。 Windows XP では、ThreeDBorderWindow によってクライアント領域に 3D 境界線が追加され、ウィンドウの表示方法に影響を与えていました。 Windows 7 以降では、2 つのスタイルの違いが最小限に抑えられています。

WindowStyle は、XAML マークアップまたはコードを使用して設定できます。 ウィンドウの有効期間中に変更される可能性は低いので、ほとんどの場合、XAML マークアップを使用して構成します。

<Window 
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    WindowStyle="ToolWindow">
</Window>

四角形以外のウィンドウ スタイル

WindowStyle で使用できる境界線のスタイルでは十分ではない状況もあります。 たとえば、Microsoft Windows Media Player で使用されるような、四角形以外の境界線を持つアプリケーションを作成する場合があります。

たとえば、次の画像に示す吹き出しウィンドウを検討してください。

クリップされた領域とカスタム図形が含まれる WPF ウィンドウのスクリーンショット。

この種類のウィンドウは、WindowStyle プロパティを None に設定し、Window が透明度に対して持つ特殊なサポートを使用することによって作成できます。

<Window x:Class="WindowsOverview.ClippedWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        Title="ClippedWindow" SizeToContent="WidthAndHeight"
        WindowStyle="None" AllowsTransparency="True" Background="Transparent">
    <Grid Margin="20">
        <Grid.RowDefinitions>
            <RowDefinition Height="*"/>
            <RowDefinition Height="20"/>
        </Grid.RowDefinitions>

        <Rectangle Stroke="#FF000000" RadiusX="10" RadiusY="10"/>
        <Path Fill="White" Stretch="Fill" Stroke="#FF000000" HorizontalAlignment="Left" Margin="15,-5.597,0,-0.003" Width="30" Grid.Row="1" Data="M22.166642,154.45381 L29.999666,187.66699 40.791059,154.54395"/>
        <Rectangle Fill="White" RadiusX="10" RadiusY="10" Margin="1"/>
        
        <TextBlock HorizontalAlignment="Left" VerticalAlignment="Center" FontSize="25" Text="Greetings!" TextWrapping="Wrap" Margin="5,5,50,5"/>
        <Button HorizontalAlignment="Right" VerticalAlignment="Top" Background="Transparent" BorderBrush="{x:Null}" Foreground="Red" Content="❌" FontSize="15" />

        <Grid.Effect>
            <DropShadowEffect BlurRadius="10" ShadowDepth="3" Color="LightBlue"/>
        </Grid.Effect>
    </Grid>
</Window>

値をこの組み合わせで使用し、ウィンドウが透明にレンダリングされるように設定します。 この状態では、ウィンドウの非クライアント領域の表示ボタンを使用できないため、独自に提供する必要があります。

タスク バーのプレゼンス

ウィンドウの既定の表示には、タスク バー ボタンが含まれます。 一部の種類のウィンドウには、WindowStyle プロパティが ToolWindow に設定されたメッセージ ボックス、ダイアログ ボックス、ウィンドウなどのタスク バー ボタンがありません。 ウィンドウのタスク バー ボタンを表示するかどうかは、ShowInTaskbar プロパティを設定することによって制御できます (既定値は true)。

<Window 
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    ShowInTaskbar="False">
</Window>

その他の種類のウィンドウ

NavigationWindow は、ナビゲーション可能なコンテンツをホストするように設計されたウィンドウです。

ダイアログ ボックスは、ユーザーから情報を収集して機能を完了するためによく使用されるウィンドウです。 たとえば、ユーザーがファイルを開く場合は、ユーザーからファイル名を取得するために、アプリケーションによって [ファイルを開く] ダイアログ ボックスが表示されます。 詳細については、「ダイアログ ボックスの概要」を参照してください。

関連項目