はじめに
WPFは、メッセージボックスやコモンダイアログボックスを表示する機能を持っていますが、それぞれダイアログボックスの形状や機能が決まっていて、自分の好きなようにカスタマイズすることができません。Windowクラスを使うと独自のダイアログを作成できますが、いざ作るとなると結構手間がかかってしまいます。
ComponentOne Studio Enterprise 2011J(ComponentOne Studio for WPF 2011J)のWindows for WPFコンポーネントに含まれるC1Windowコントロールは、ウィンドウを1つのコントロールにしたもので、簡単にモーダル・モードレスのウィンドウを作成できます。
そこで今回は、このC1Windowコントロールを使い、アプリケーションの概要を紹介するモーダルウィンドウと、メインページの背景色と枠線を設定できるモードレスパネルを持つアプリケーションを作成してみます。
対象読者
Visual Basic、Visual C# 2010を使ってプログラムを作ったことのある人
必要な環境
Visual Basic 2010、Visual C# 2010、Visual Studio 2010でプログラムが作れる環境。なお、本プログラムはWindows Vista上で動作するVisual Studio 2010を使用して作成し、動作確認を行っています。
動作環境として、あらかじめ.NET Framework 4.0がインストールされている必要があります。動作するOSは、以下を参照ください。
OS | 32ビット(x86) | 64ビット(x64) |
Windows XP 日本語版 | ● | ● |
Windows Vista 日本語版 | ● | ● |
Windows 7 日本語版 | ● | ● |
Windows Server 2003 日本語版 | ● | ● |
Windows Server 2008 日本語版 | ● | ● |
Windows Server 2008 R2 日本語版 | - | ● |
コンポーネントのインストール
この記事の手順を試すには、Visual Studio、Visual Basic、Visual C#の開発環境にComponentOne Studio Enterprise 2011J(または、ComponentOne Studio for WPF 2011J)をインストールする必要があります。インストーラは、グレープシティのWebページからダウンロードできます。
製品のトライアル版一覧ページにてダウンロードしたい製品にチェックを入れ、ページ右上部の[申込フォーム]をクリックしてグレープシティのWebサイトへ必要情報を登録すると、添付トライアルライセンスキーファイルとダウンロードサイトを記載したE-Mailが送られてきますので、ここからダウンロードします。制限事項などの詳細については、インストーラに同梱されているリリースノートを参照ください。
参照の追加
ComponentOne Studio Enterprise 2011J(または、ComponentOne Studio for WPF 2011J)をインストールしたら、使用するコンポーネントを追加します。今回のコントロールは、コードから作成して使用するので、ツールボックスに追加するのではなくプロジェクトの[参照の追加]から参照の設定を行います。追加する参照は、「.NET」にある、コンポーネント名が「C1.WPF」のものです。
C1Windowコントロールについて
C1Windowコントロールは、WPFアプリケーション内にウィンドウを表示します。C1Windowコントロールを表示する際に、モーダル/モードレスの形態を選ぶことができます。ウィンドウがモーダルおよびモードレスで表示されているときに、ユーザーが他のウィンドウを操作できるかどうかも指定できます。
C1Windowコントロールは、ページ上のどの要素の子でもなく、C1Windowオブジェクトをルート要素とする個別のXAMLファイルで定義することもできます。
さらに、ウィンドウのサイズを変更できるかどうかを簡単に指定でき、ウィンドウが小さくてすべてのコンテンツを表示できなくなると自動的にスクロールバーが追加されます。また、[最小化][元のサイズに戻す][閉じる]などのボタンを標準で装備し、デフォルトでウィンドウの現在の状態を設定できます。ウィンドウを最大化できないように設定することも可能です。
C1Windowコントロールは通常のダイアログボックスと同様に、ヘッダーとコンテンツ領域という2つの主要な要素があります。
ヘッダー領域には、タイトルテキスト、[最小化]ボタン、[最大化]ボタン、[閉じる]ボタンなどの通常のキャプションバーと同じ要素が含まれています。ヘッダーのテキストはHeaderプロパティで設定します。Headerプロパティを「UIElement」に設定も可能なため、例えば、キャプションバーのテキストの横にアイコンを追加することなどもできます。
また、ShowCloseButton、ShowMaximizeButton、ShowMinimizeButtonの各プロパティを使用して、[最小化][最大化][閉じる]ボタンの表示を設定します。デフォルトでは、この3つのプロパティはすべて「True」で、これらのボタンは表示状態になっています。
コンテンツ領域は、Contentプロパティを使って設定します。コンテンツ領域には、コントロール、コントロールを含むパネル(Grid、StackPanelなど)、テキストなどの複数のコントロールや要素を置くことができます。
WPFアプリケーションの作成
では、さっそくC1Windowコントロールを使ってWPFアプリケーションを作成しましょう。作成するアプリケーションは、アプリケーションの概要を紹介するモーダルウィンドウと、メインページの背景色と枠線を設定できるモードレスパネルを持ったアプリケーションです。
GUIのデザイン
ページデザイン時では、2つのC1Windowコントロールをそれぞれ専用のUserControlオブジェクトに配置し、その上にCheckBox、Imageコントロールを配置したものを作成して、それぞれButtonコントロールとTextBlockコントロールから呼び出すようにします。
メインとなるページ「MainWindow.xaml」では、ButtonとTextBlockコントロールを配置するだけです。アプリケーションの概要を紹介するモーダルウィンドウ「about.xaml」には、Imageコントロールを配置して画像を表示させます。モードレスパネル「toolbox.xaml」では、メインページの背景色を枠線を設定するための2つのCheckBoxコントロールを配置します。
メインページ「MainWindow.xaml」のデザイン
まず、このページを操作できるように名前をつけます。そして、背景色と枠線を設定しておきます。また、それぞれの両端にButtonコントロールとTextBlockコントロールを配置し、イベントハンドラを作成します。
Buttonコントロールの場合はClickイベントを使用しますが、TextBlockコントロールにはClickイベントがないので、「MouseLeftButtonDown」というイベントを利用することにします。
<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="450" Width="700" xmlns:my="http://schemas.componentone.com/wpf/Basic" Name="MainWindow1" BorderBrush="Blue" BorderThickness="2" Background="White" > <Grid> <TextBlock Height="20" HorizontalAlignment="Left" Margin="461,12,0,0" Name="TextBlock1" Text="このアプリケーションについて" VerticalAlignment="Top" Width="187" Foreground="DarkSalmon" MouseLeftButtonDown="TextBlock1_MouseLeftButtonDown" /> <Button Content="設定..." Height="22" HorizontalAlignment="Left" Margin="16,10,0,0" Name="Button1" VerticalAlignment="Top" Click="Button1_Click" Width="67" /> </Grid> </Window>
モーダルウィンドウ「about.xaml」のデザイン
このウィンドウは、C1Windowコントロールを直接デザインするのではなく、プロジェクトにWPFユーザーコントロールを追加し、ここにコントロールを配置してデザインします。そして、このユーザーコントロールを、C1WindowコントロールのContentプロパティに組み込みます。
まず、プロジェクトの上でショートカットメニューを表示し、[追加]-[新しい項目]を選びます。
テンプレートで[WPF]-[ユーザーコントロール(WPF)]を選び、名前を「about.xaml」に変更し[追加]ボタンを押します。
Imageコントロールを配置し、画像ファイル(ここでは「setoseto.jpg」)をSourceプロパティに設定して、コントロールのサイズを画像サイズに合わせます。
ユーザーコントロールの背景色のグラデーションと枠線を設定します。このダイアログは、アプリケーションの名称とバージョン番号を表示するだけなので、これでできあがりです。
<UserControl x:Class="Wpf_c1window_cs.about" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" xmlns:d="http://schemas.microsoft.com/expression/blend/2008" mc:Ignorable="d" d:DesignHeight="210" d:DesignWidth="375" BorderThickness="2" BorderBrush="LimeGreen"> <UserControl.Background> <LinearGradientBrush EndPoint="1,0.5" StartPoint="0,0.5"> <GradientStop Color="#FF694C24" Offset="0" /> <GradientStop Color="White" Offset="1" /> </LinearGradientBrush> </UserControl.Background> <Grid Height="200" Width="357"> <Grid.ColumnDefinitions> <ColumnDefinition Width="343*" /> <ColumnDefinition Width="14*" /> </Grid.ColumnDefinitions> <Image Height="150" Name="Image1" Stretch="Fill" Width="300" Source="/Wpf_c1window_vb;component/Images/setoseto.jpg" Margin="28,25,14,25" /> </Grid> </UserControl>
モードレスパネル「toolbox.xaml」のデザイン
先ほどのモーダルウィンドウと同様、C1Windowコントロールを直接デザインするのではなく、プロジェクトにWPFユーザーコントロールを追加し、ここにコントロールを配置してデザインします。
まず、プロジェクトの上でショートカットメニューを表示して[追加]-[新しい項目]を選び、もう1つ[WPF]-[ユーザーコントロール(WPF)]を追加します。名前は「toolbox.xaml」にします。
続いて、CheckBoxコントロールを配置し、それぞれContentプロパティを「ページの背景色」「枠線」に変えます。CheckedイベントとUncheckedイベントのイベントハンドラを作成します。「枠線」チェックボックスだけ、IsCheckedプロパティを「True」にしてチェックを付けておきます。
<UserControl x:Class="Wpf_c1window_cs.toolbox" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" xmlns:d="http://schemas.microsoft.com/expression/blend/2008" mc:Ignorable="d" d:DesignHeight="81" d:DesignWidth="128"> <Grid Height="70" Width="121" HorizontalAlignment="Left" VerticalAlignment="Top"> <CheckBox Content="ページの背景色" Height="24" Name="CheckBox1" Width="121" Checked="CheckBox1_Checked" Unchecked="CheckBox1_Unchecked" VerticalAlignment="Top" HorizontalAlignment="Left" /> <CheckBox Content="枠線" Height="23" IsChecked="True" Margin="0,21,44,0" Name="CheckBox2" VerticalAlignment="Top" Width="108" Checked="CheckBox2_Checked" Unchecked="CheckBox2_Unchecked"/> </Grid> </UserControl>
コードの作成
作成した2つのウィンドウは、メインページのボタンとテキストをクリックすると、呼び出して表示するようにします。この呼び出しの時に、作成した2つのユーザーコントロールをそれぞれC1Windowコントロールに組み込み、ダイアログボックスとして表示します。
また、ツールボックスでは、CheckBoxコントロールのチェックのオンオフで、メインページのプロパティを操作する処理を組み込みます。
モーダルウィンドウの呼び出し処理
C1Windowコントロールはコードから作成し、このContentプロパティにモーダルウィンドウの「about」オブジェクトを作成して設定します。
このウィンドウは、ウィンドウを閉じないとメインページが操作できない「モーダル」ウィンドウとして表示させます。
各コードの内の番号は、次の処理を行っています。
- TextBlockのイベントハンドラで、C1Windowクラスのコンストラクタを実行して変数に格納
- このクラスのHeaderプロパティでタイトルバーの文字列を設定
- ウィンドウのサイズを指定(タイトルバーが付くので、作成したユーザーコントロールよりも少し大きめに設定)
- ユーザーコントロールのコンストラクタを実行して、オブジェクトをContentプロパティに設定
- ダイアログをアプリケーションの中心に置きたい場合は、CenterOnScreenメソッドを実行
- モーダル表示時のメインウィンドウは、デフォルトでは薄いグレー表示。ModalBackgroundプロパティを使うとこの色を変えることが可能(プロパティの値はBrushオブジェクト)
- アバウトダイアログは最小化・最大化する必要がないため、これらのボタンを非表示
- C1Windowコントロールのプロパティ設定後、ShowModalメソッドを実行してモーダル表示
Imports C1.WPF 'アバウトダイアログページをC1Windowに組み込んで使う Private Sub TextBlock1_MouseLeftButtonDown(ByVal sender As System.Object, ByVal e As System.Windows.Input.MouseButtonEventArgs) (1) Dim wnd As New C1Window() (2) wnd.Header = "このアプリケーションについて" (3) wnd.Height = 250 wnd.Width = 400 (4) wnd.Content = New about() (5) wnd.CenterOnScreen() (6) wnd.ModalBackground = New SolidColorBrush(Colors.Azure) (7) wnd.ShowMinimizeButton = False wnd.ShowMaximizeButton = False (8) wnd.ShowModal() End Sub
using C1.WPF; // アバウトダイアログページをC1Windowに組み込んで使う private void TextBlock1_MouseLeftButtonDown(object sender, MouseButtonEventArgs e) { (1) C1Window wnd = new C1Window(); (2) wnd.Header = "このアプリケーションについて"; (3) wnd.Height = 250; wnd.Width = 400; (4) wnd.Content = new about(); (5) wnd.CenterOnScreen(); (6) wnd.ModalBackground = new SolidColorBrush(Colors.Azure); (7) wnd.ShowMinimizeButton = false; wnd.ShowMaximizeButton = false; (8) wnd.ShowModal(); }
ツールボックスの呼び出し処理
ツールボックスも、アバウトダイアログと同様にコードからC1Windowコントロールを作成します。ただし、ツールボックスはアバウトダイアログと違い、ダイアログを表示しながらアプリケーションを操作できる「モードレス表示」にします。
各コードの内の番号は、次の処理を行っています。
- C1Windowクラスのコンストラクタを実行して変数に格納
- Headerプロパティでタイトルバーの文字列を設定
- ウィンドウのサイズを指定
- ユーザーコントロールのコンストラクタを実行し、オブジェクトをContentプロパティに設定
- ツールボックスの場合は、アプリケーションの中心ではなく左端に配置したいので、Top/Leftプロパティを使って表示位置を指定
- ツールボックスの最小化・最大化の必要はないので、これらのボタンを非表示
- ツールボックスの場合はモードレス表示にするため、Showメソッドを実行
'ツールボックスページをC1Windowに組み込んで使う Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.Windows.RoutedEventArgs) (1) Dim wnd As New C1Window() (2) wnd.Header = "設定" (3) wnd.Height = 120 wnd.Width = 200 (4) wnd.Content = New Toolbox() (5) wnd.Left = 10 wnd.Top = 40 (6) wnd.ShowMinimizeButton = False wnd.ShowMaximizeButton = False (7) wnd.Show() End Sub
private void Button1_Click(object sender, RoutedEventArgs e) { (1) C1Window wnd = new C1Window(); (2) wnd.Header = "設定"; (3) wnd.Height = 120; wnd.Width = 200; (4) wnd.Content = new toolbox(); (5) wnd.Left = 10; wnd.Top = 40; (6) wnd.ShowMinimizeButton = false; wnd.ShowMaximizeButton = false; (7) wnd.Show(); }
CheckBoxコントロールがクリックされた時の処理
ツールボックスに配置したCheckBoxコントロールでは、メインページの背景色と枠線を操作するようにします。それぞれのCheckBoxコントロールのChecked/Uncheckedイベントハンドラでこの処理を実行します。メインページをユーザーコントロールから操作する場合は、「Application.Current.MainWindow」を使用してメインページをオブジェクトとして取得し、各プロパティを操作します。
また、枠線の表示/非表示は、枠線の太さの設定によって実装しています。この処理では、BorderThicknessプロパティを使用し、プロパティの値にThicknessオブジェクトを設定します。クラスのコンストラクタの引数で、縦横四辺の枠線の太さを変えることができます。
Public Class Toolbox Private mw As Window = Application.Current.MainWindow Private Sub CheckBox1_Checked(ByVal sender As System.Object, ByVal e As System.Windows.RoutedEventArgs) mw.Background = New SolidColorBrush(Colors.BlueViolet) End Sub Private Sub CheckBox1_Unchecked(ByVal sender As System.Object, ByVal e As System.Windows.RoutedEventArgs) mw.Background = New SolidColorBrush(Colors.White) End Sub Private Sub CheckBox2_Checked(ByVal sender As System.Object, ByVal e As System.Windows.RoutedEventArgs) Dim th2 As New Thickness(2, 2, 2, 2) mw.BorderThickness = th2 End Sub Private Sub CheckBox2_Unchecked(ByVal sender As System.Object, ByVal e As System.Windows.RoutedEventArgs) Dim th0 As New Thickness(0, 0, 0, 0) mw.BorderThickness = th0 End Sub End Class
public partial class toolbox : UserControl { public toolbox() { InitializeComponent(); } private Window mw = Application.Current.MainWindow; private void CheckBox1_Checked(object sender, RoutedEventArgs e) { mw.Background = new SolidColorBrush(Colors.BlueViolet); } private void CheckBox1_Unchecked(object sender, RoutedEventArgs e) { mw.Background = new SolidColorBrush(Colors.White); } private void CheckBox2_Checked(object sender, RoutedEventArgs e) { Thickness th2 = new Thickness(2, 2, 2, 2); mw.BorderThickness = th2; } private void CheckBox2_Unchecked(object sender, RoutedEventArgs e) { Thickness th0 = new Thickness(0,0,0,0); mw.BorderThickness = th0; } }
まとめ
C1Windowコントロールを使用すると、手軽にカスタムウィンドウを作成できます。ダイアログのデザインも、通常のWPFページと同様にデザイナを使ってXAMLで作成できるので、好きなコントロールを使って自由なレイアウトを表現できます。
C1Windowコントロールを呼び出すメソッドによって、モードレス/モーダルを切り替えることができるため、サブウィンドウが必要なアプリケーションの作成には大いに威力を発揮するコントロールだと思います。