WPF のウィンドウ(その2)の続きです。

Window のサイズ

 Window のサイズは SizeToContent プロパティで制御します。SizeToContent を WidthAndHeight にすると Window のコンテンツに合わせて、サイズが自動調整されるようになります。これはすばらしいことで Windows のビジュアルスタイルに左右されることなく、クライアント領域のサイズが決定されるようになります。開発時のスタイルと実行時のスタイルが違っても、クライアント領域のサイズは自動的に同じになるのです。

 従来のようにサイズを設定するには SizeToContent に Manual を設定します。ただしこの時は、非クライアント領域を含めたサイズ指定であることを意識しなければなりません。

 残念なことに SizeToContent プロパティの既定値は Manual になっています。おそらく WidthAndHeight を設定した場合に、詰まってしまうためだと思います。クライアント領域のサイズを指定して表示できればいいのですが、Form の ClientSize プロパティに相当するものが Window にはありません。それでも次のようにすれば Window のクライアント領域のサイズを指定して表示することができます(Window のコンテンツに Grid1 という名前の Grid が配置されています)。

Window のクライアント領域のサイズを指定して表示する例
Private Class Window1
    Private Sub Window1_Initialized(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Initialized
        ' ClientSize プロパティの設定を再現します。
        Me.SizeToContent = Windows.SizeToContent.WidthAndHeight
        Me.Grid1.Width = 300
        Me.Grid1.Height = 300
    End Sub
    Private Sub Window1_Loaded(ByVal sender As Object, ByVal e As System.Windows.RoutedEventArgs) Handles Me.Loaded
        ' このままだとコンテンツのサイズが固定されるので Window のサイズに合わせるようにします。
        Me.SizeToContent = Windows.SizeToContent.Manual
        Me.Grid1.Width = Double.NaN
        Me.Grid1.Height = Double.NaN
    End Sub
End Class

 Initialized イベントで指定しているコンテンツ(Grid1)のサイズが、ClientSize プロパティ相当になります。Loaded イベントの時点で Window のサイズは、そのコンテンツのサイズに調整されています。表示した後はコンテンツのサイズを Window のサイズに合わせるために Width と Height に Double.NaN を設定し、サイズを未設定の状態にしています。

 これを XAML だけでやろうとした場合、Initialized イベントのコードはできますが、Loaded イベントのコードを XAML だけでできるかちょっとわかりません。まだ XAML になれていないので、今はコードで書いたほうが楽です。

 ClientSize プロパティとして Width と Height を設定しましたが、この値を取得する時は、表示されているサイズを返さないことがあります。確実に表示されているサイズを取得するには ActualWidth と ActualHeight プロパティを使用します。これは読み取り専用になっています。このようなことから WPF では Window やコントロールなどのサイズは、直接設定するのではなく Grid などのレイアウトコントロールに任せるようにしていった方がいいと思います。

まとめ

  • Window のサイズは SizeToContent プロパティで制御する。
  • SizeToContent が WidthAndHeight のときは、コンテンツのサイズに自動調整される。
  • サイズを直接指定する場合は SizeToContent に Manual を設定する。
  • Window のクライアント領域のサイズを設定したい時は、コンテンツのサイズを予め設定しておくことで対応できる。
  • サイズの設定はレイアウトコントロールに任せる。

 Window のサイズ(コントロールも含む)は Form の概念とかなり変更されている部分だと思います。WidthAndHeight でクライアント領域のサイズが開発時と実行時でようやく同じにできるようになったと思ったのですが、任意のサイズでクライアント領域を設定する方法が用意されていないのが少し残念です。Window のサイズを直接設定した場合でも、コンテンツのサイズは自動調整されるように作ると思うので、少しくらい Window のサイズが変更されても見た目が崩れることはないですよね。それが WPF のいいところだと思います。