はじめに
アプリケーションの1つのウィンドウに、いろいろな機能を組み込みたい時がありますが、1ページに収められる量には限界があります。このような時は、タブページを使用すると、1つの画面内でページを切り替えて使うことができます。機能や情報を多く組み込むことができるだけでなく、見やすい形に整理することも可能です。
ComponentOne Studio Enterprise 2011J(ComponentOne Studio for WPF 2011J)のTabControl for WPFコンポーネントに含まれるC1TabControlコントロールは、タブおよびタブに対応するページを追加できるため、画面領域を消費せず、大量の情報を届けることが可能です。
今回は、このC1TabControlコントロールを使って、複数の操作機能を1つのウィンドウにまとめたWPFアプリケーションを作成してみました。
対象読者
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)をインストールしたら、ツールボックスに専用のタブを作成し、使用するコンポーネントを追加します。追加するコンポーネントは、[WPFコンポーネント]でアセンブリ名が「C1.WPF」の「C1TabControl」コントロールです。
C1TabControlコントロールについて
C1TabControlコントロールは、WPF上のページに複数のタブページを提供するコンテナコントロールで、各タブページにコントロールを配置して使用します。
C1TabControlコントロールの要素
C1TabControlコントロールは、タブ、タブストリップ、タブページで構成されています。

C1TabControlコントロールの各タブは、C1TabItemクラスによって表します。タブに表示するヘッダー文字列は、C1TabItemクラスのHeaderプロパティで設定します。C1TabControlコントロールのタブストリップは、1つ以上のC1TabItemオブジェクトをコントロールに追加すると作成されます。ストリップ内の各タブは、それぞれのタブページに関連付けられています。
C1TabControlコントロールはコンテナコントロールなので、タブページを追加した時点では中身は空白です。コントロールを配置する場合は、Contentプロパティにコントロールを組み込みます。ただし、C1TabItemクラスは子要素を一度に1つだけ受け入れることができるようになっているので、そのままコントロールを配置した場合は1つのコントロールしか配置できません。複数のコントロールを使用したい場合は、GridやStackPanelコントロールなどと組み合わせて配置します。
<c1:C1TabItem> <c1:C1TabItem.Content> <StackPanel> <TextBlock Text="Hello"/> <TextBlock Text="World"/> </StackPanel> </c1:C1TabItem.Content> </c1:C1TabItem>

C1TabControlコントロールの主な特徴
-
スクロール要素
C1TabControlコントロールでは、タブがコントロールで指定した幅または高さを超えたとき、スクロールボタンが自動的に挿入されます。
-
タブストリップの配置
デフォルトで、タブストリップはC1TabControlコントロールの上部に表示されます。ただし、TabStripPlacementプロパティによって、コントロールの上下左右のいずれにも配置できます。
コントロールの上下左右のいずれにも配置可能(ヘルプファイルより抜粋) -
タブクローズオプション
ユーザーがタブを閉じることができるかどうかを設定できます。また、[閉じる]ボタンを表示する場所を、各タブ項目内またはタブストリップ外のグローバルな場所に指定できます。
-
メニューでのタブの表示
C1TabControlコントロールでは、複数のタブページが作られると自動的にページのリストを作成し、ドロップダウンメニューからタブページを開くことができるようになります。
ドロップダウンメニューからタブページを開くことができる(ヘルプファイルより抜粋) -
ヘッダーの形状をカスタマイズします
C1TabControlコントロールのTabItemShapeプロパティをRounded、Rectangle、Slopedから選択し、タブヘッダーの形状を変更できます。
タブ形状を変更できる(ヘルプファイルより抜粋) -
新しいタブページの表示
Internet Explorer 8のように新しいタブページを開くための機能を実装しています。ユーザーは専用のタブをクリックするだけで、新しいタブページを追加できます。
新しいタブページを開くための専用タブ -
ヘッダーの重ね合わせの方法を選べる
タブを重ね合わせる際に、右側を奥にするか、左側を奥にするか、あるいは選択した位置から左右に奥まっていくか設定できます。選択されているタブは一番手前に表示されます。
ヘッダーを重ね合わせる位置を設定できる -
背景の変更
タブの外観を維持しながら、その背景を変更できます。簡単な機能のように見えますが、テンプレート全体をカスタマイズすることなく背景のみを変更できるタブコントロールは、現在、C1TabControl以外に存在しません。
-
ヘッダーの重なり
タブ項目のヘッダー間の重なりをカスタマイズすることにより、Microsoft Visual Studioの[ドキュメント]タブのような階段状のタブを表示できます。
WPFアプリケーションの作成
では、さっそくC1TabControlコントロールを使ってWPFアプリケーションを作成しましょう。今回作成するのは、C1TabControlコントロールを2つ使用したアプリケーションです。
GUIのデザイン
1つ目のC1TabControlコントロールでは、テキストファイルを読みこんでその内容をTextBoxコントロールで表示します。ボタンを押すたびに、テキストファイルの内容を新しいタブページとTextBoxコントロールを作成して表示します。ファイル名の選択には、WPFの「ファイルを開く」ダイアログボックスを使用します。
2つ目のC1TabControlコントロールは、ファイルを開くためのボタンと、1つ目のC1TabControlコントロールのタブ形状と表示位置を設定するラジオボタンを持ちます。
使用するコントロールは、C1TabControlコントロールが2つと、Button、RadioButton、TextBlock、OpenFileDialogです。OpenFileDialogコントロールについては、コードから起動します。

設定用C1TabControlコントロールの作成
まずは、C1TabControlコントロールを2つ作成します。
ツールボックスからC1TabControlコントロールのアイコンを選び、ウィンドウにドラッグ&ドロップします。
<Grid Height="438" Width="766"> <c1:C1TabControl Height="358" HorizontalAlignment="Left" Name="c1TabControl1" VerticalAlignment="Top" Width="535" Margin="204,30,0,0"> </c1:C1TabControl>
配置したら右側に移動し、もう1つC1TabControlコントロールのアイコンをドラッグ&ドロップして2つ作成します。右側のC1TabControlコントロールが「c1TabControl1」、左側のC1TabControlコントロールが「c1TabControl2」という名前になります。
<c1:C1TabControl Height="300" HorizontalAlignment="Left" Margin="12,30,0,0" Name="c1TabControl2" VerticalAlignment="Top" Width="186"> </c1:C1TabControl>
次に、設定用のタブコントロールをデザインしていきます。
左側のC1TabControlコントロール「c1TabControl2」をクリックし、プロパティウィンドウの「Items」プロパティにある[...]ボタンをクリックします。コレクションエディタが起動するので、[追加]ボタンを2回押してタブページを2つ追加します。
それぞれのC1TabItemオブジェクトのHeaderプロパティを、XAMLコードで記述します。
<c1:C1TabItem Header="ファイルを開く" /> <c1:C1TabItem Header="設定" />
「ファイルを開く」タブページにButtonコントロールを配置し、Clickイベントハンドラを作成します。
<Button Content="開く" Height="39" Name="button1" Click="button1_Click" Width="104" />
そのまま「ファイルを開く」タブページを選択した状態で、プロパティウィンドウの「ブラシ-Background」プロパティをクリックします。カラーパレットが表示されるので、グラデーションカラーを選んで設定します。これで、アクティブでないときにタブの背景色がグラデーションで塗りつぶされます。
<c1:C1TabItem Header="ファイルを開く"> <c1:C1TabItem.Background> <LinearGradientBrush EndPoint="1,0.5" StartPoint="0,0.5"> <GradientStop Color="#FF3FEBEB" Offset="0" /> <GradientStop Color="#FFE6FFFF" Offset="1" /> </LinearGradientBrush> </c1:C1TabItem.Background> <Button Content="開く" Height="39" Name="button1" Click="button1_Click" Width="104" /> </c1:C1TabItem>

「設定」タブページをクリックし、ここにStackpanelとTextBlockを2つと、それぞれのStackPanel上にRadioButtonコントロールを配置します。RadioButtonコントロールには、すべてCheckedイベントハンドラを設定します。また、「ファイルを開く」タブページと同様に、タブの背景色をグラデーションで塗りつぶし、文字色も変えておきます。
RadioButtonコントロールは、「ラウンド」と「上側」だけ「IsChecked」プロパティを「True」にしておきます。これは、C1TabControlコントロールはデフォルトでタブの形状がラウンドで上側に表示されるためです。
<c1:C1TabItem Header="設定" Foreground="DarkCyan"> <c1:C1TabItem.Background> <LinearGradientBrush EndPoint="0.5,1" StartPoint="0.5,0"> <GradientStop Color="#FFDBEB85" Offset="0.006" /> <GradientStop Color="#FFF5F0B0" Offset="1" /> </LinearGradientBrush> </c1:C1TabItem.Background> <StackPanel Height="245" Name="stackPanel1" Width="145" VerticalAlignment="Top"> <TextBlock Height="22" Name="textBlock1" Text="タブ形状" /> <RadioButton Content="スクエア" Height="28" Name="radioButton1" Width="100" Checked="radioButton1_Checked" /> <RadioButton Content="ラウンド" Height="24" Name="radioButton2" Width="100" Checked="radioButton2_Checked" IsChecked="True" /> <RadioButton Content="スロープ" Height="23" Name="radioButton3" Width="100" Checked="radioButton3_Checked" /> <StackPanel Height="127" Name="stackPanel2" Width="140" VerticalAlignment="Bottom" Margin="0,10,0,0"> <TextBlock Height="23" Name="textBlock2" Text="タブの位置" /> <RadioButton Content="上側" Height="30" Name="radioButton4" Width="100" Checked="radioButton4_Checked" IsChecked="True" /> <RadioButton Content="下側" Height="28" Name="radioButton5" Width="100" Checked="radioButton5_Checked" /> <RadioButton Content="右側" Height="27" Name="radioButton6" Width="100" Checked="radioButton6_Checked" /> <RadioButton Content="左側" Height="25" Name="radioButton7" Width="100" Checked="radioButton7_Checked" /> </StackPanel> </StackPanel> </c1:C1TabItem>

テキスト表示用C1TabControlコントロールの設定
今度は、テキスト表示用C1TabControlコントロールの設定を行います。
右側に配置したC1TabControlコントロールですが、デザイン時点ではタブページは追加しません。ここでは、コントロールの右端に[閉じる]ボタンとドロップダウンリストを表示するボタンの設定のみ行います。
コントロールの右端に[閉じる]ボタンを設定するには、「TabItemClose」プロパティの値を「GlobalClose」に設定します。これで、「閉じる」ボタンは個々のタブページには付かず、C1TabControlコントロールに1つだけ付きます。
また、タブページのリストを表示するドロップダウンリストボタンを使うには、「TabStripMenuVisibility」プロパティを「Visible」に設定します。
<c1:C1TabControl Height="358" HorizontalAlignment="Left" Name="c1TabControl1" VerticalAlignment="Top" Width="535" TabItemClose="GlobalClose" TabStripMenuVisibility="Visible" TabStripPlacement="Top" Margin="204,30,0,0"> </c1:C1TabControl>
後は、すべてコードからタブページとTextBoxコントロールを追加していきます。
テキストファイルを読み込む処理
ここからは、コードでテキストファイルを読み込み、タブページとTextBoxコントロールを作成してファイルの中身を表示する処理を組み立てます。この処理は、ButtonコントロールのClickイベントハンドラで行います。
「ファイルを開く」ダイアログボックスの表示
まず、「ファイルを開く」ダイアログボックスを表示し、読み込むテキストファイル名を取得します。
ここで、WindowsフォームでもおなじみのWin32APIのOpenFileDialogクラスを使用します。コンストラクタでオブジェクト化し、ShowDialogメソッドを実行すると、「ファイルを開く」ダイアログボックスが表示されます。ユーザーがファイルを選ぶと、OpenFileDialogクラスのFileNameプロパティに、選択したファイル名をドライブ名からのフルパスで格納します。また、SafeFileNameプロパティにはファイル名のみを格納するため、それぞれの値を変数に格納しておきます。
Imports C1.WPF Imports System.IO Private Sub button1_Click(ByVal sender As System.Object, ByVal e As System.Windows.RoutedEventArgs) ' ファイルの読み込み Dim fname As String = "" Dim shortfname As String = "" Dim dlg As New Microsoft.Win32.OpenFileDialog() dlg.FileName = "*.txt" ' Default file name dlg.DefaultExt = ".txt" ' Default file extension dlg.Filter = "テキストファイル (.txt)|*.txt" ' Filter files by extension ' ダイアログの表示 Dim result? As Boolean = dlg.ShowDialog() If result = True Then ' Open document fname = dlg.FileName shortfname = dlg.SafeFileName
using System.IO; using C1.WPF; private void button1_Click(object sender, RoutedEventArgs e) { // ファイルの読み込み string fname = ""; string shortfname = ""; Microsoft.Win32.OpenFileDialog dlg = new Microsoft.Win32.OpenFileDialog(); dlg.FileName = "*.txt"; // Default file name dlg.DefaultExt = ".txt"; // Default file extension dlg.Filter = "テキストファイル (.txt)|*.txt"; // Filter files by extension // ダイアログの表示 Nullable<bool> result = dlg.ShowDialog(); if (result == true) { fname = dlg.FileName; shortfname = dlg.SafeFileName;
タブページとTextBoxコントロールの追加処理
ユーザーが選択したファイル名を取得したら、タブページ「TabItem」オブジェクトを作成し、C1TabControlコントロールに追加するとともに、Headerプロパティに開いたファイル名を設定します。
また、TextBoxコントロールを作成し、TabItemオブジェクトのContentプロパティに設定します。これで、タブページにTextBoxコントロールが組み込まれます。このとき、TextBoxコントロールでは文字列の折り返しを設定し、垂直方向のスクロールバーを設定しておきます。
そして、FileクラスのReadAllTextメソッドでファイルの中身をすべて取り出し、TextBoxコントロールのTextプロパティに設定して表示します。
' タブページとTextBoxの追加 'タブを作成し、コンテンツを追加します Dim TabItem As New C1TabItem() c1TabControl1.Items.Add(TabItem) TabItem.Header = shortfname Dim tbox1 As TextBox = New TextBox() tbox1.TextWrapping = TextWrapping.WrapWithOverflow tbox1.VerticalScrollBarVisibility = ScrollBarVisibility.Auto TabItem.Content = tbox1 tbox1.Text = File.ReadAllText(fname, Text.Encoding.Default) End If End Sub
// タブページとTextBoxの追加 C1TabItem tabitem = new C1TabItem(); c1TabControl1.Items.Add(tabitem); tabitem.Header = shortfname; TextBox tbox1 = new TextBox(); tbox1.TextWrapping = TextWrapping.WrapWithOverflow; tbox1.VerticalScrollBarVisibility = ScrollBarVisibility.Auto; tabitem.Content = tbox1; tbox1.Text = File.ReadAllText(fname, Encoding.Default); } }
RadioButtonコントロールのイベントハンドラ処理
RadioButtonコントロールがクリックされたときは、テキスト表示のC1TabControlコントロールのタブの形状と表示位置を変える処理を組み込みます。タブの形状の指定には、C1TabControlクラスのTabItemShapeプロパティを使用します。それぞれ、C1TabItemShape列挙体のメンバを設定します。
メンバ名 | 説明 |
Rectangle | 四角のタブ形状 |
Rounded | 丸いタブ形状 |
Sloped | 斜めのタブ形状 |
Ribbon | S字型タブ |
また、タブの表示位置は、C1TabControlクラスのTabStripPlacementプロパティで設定します。設定値は、C1.WPF名前空間にあるDockクラスのメンバを指定します。
Private Sub radioButton1_Checked(ByVal sender As System.Object, ByVal e As System.Windows.RoutedEventArgs) Handles radioButton1.Checked c1TabControl1.TabItemShape = C1TabItemShape.Rectangle End Sub Private Sub radioButton2_Checked(ByVal sender As System.Object, ByVal e As System.Windows.RoutedEventArgs) Handles radioButton2.Checked c1TabControl1.TabItemShape = C1TabItemShape.Rounded End Sub Private Sub radioButton3_Checked(ByVal sender As System.Object, ByVal e As System.Windows.RoutedEventArgs) Handles radioButton3.Checked c1TabControl1.TabItemShape = C1TabItemShape.Sloped End Sub Private Sub radioButton4_Checked(ByVal sender As System.Object, ByVal e As System.Windows.RoutedEventArgs) c1TabControl1.TabStripPlacement = C1.WPF.Dock.Top End Sub Private Sub radioButton5_Checked(ByVal sender As System.Object, ByVal e As System.Windows.RoutedEventArgs) c1TabControl1.TabStripPlacement = C1.WPF.Dock.Bottom End Sub Private Sub radioButton6_Checked(ByVal sender As System.Object, ByVal e As System.Windows.RoutedEventArgs) c1TabControl1.TabStripPlacement = C1.WPF.Dock.Right End Sub Private Sub radioButton7_Checked(ByVal sender As System.Object, ByVal e As System.Windows.RoutedEventArgs) c1TabControl1.TabStripPlacement = C1.WPF.Dock.Left End Sub
private void radioButton1_Checked(object sender, RoutedEventArgs e) { c1TabControl1.TabItemShape = C1TabItemShape.Rectangle; } private void radioButton2_Checked(object sender, RoutedEventArgs e) { c1TabControl1.TabItemShape = C1TabItemShape.Rounded; } private void radioButton3_Checked(object sender, RoutedEventArgs e) { c1TabControl1.TabItemShape = C1TabItemShape.Sloped; } private void radioButton4_Checked(object sender, RoutedEventArgs e) { c1TabControl1.TabStripPlacement = C1.WPF.Dock.Top; } private void radioButton5_Checked(object sender, RoutedEventArgs e) { c1TabControl1.TabStripPlacement = C1.WPF.Dock.Bottom; } private void radioButton6_Checked(object sender, RoutedEventArgs e) { c1TabControl1.TabStripPlacement = C1.WPF.Dock.Right; } private void radioButton7_Checked(object sender, RoutedEventArgs e) { c1TabControl1.TabStripPlacement = C1.WPF.Dock.Left; }
まとめ
1つのコントロールで複数のタブページを使用できれば、ページエリアを有効に使うことができるとともに、多くの機能を整理して組み込むことができます。
多機能が求められている昨今のアプリケーションでは、威力を発揮するコントロールではないでしょうか。