Shoeisha Technology Media

CodeZine(コードジン)

特集ページ一覧

複数機能を表示するタブページを持ったWPFアプリケーションの作成

ComponentOne Studio Enterprise 2011JのC1TabControlコントロールを使ったWPFアプリケーションの作成

  • ブックマーク
  • LINEで送る
  • このエントリーをはてなブックマークに追加
2011/10/17 14:00

 今回は「ComponentOne Studio Enterprise 2011J」に含まれているコンポーネントの中から、TabControl for WPFの「C1TabControlコントロール」を取りあげ、具体的なサンプルアプリケーションに沿って解説していきます。本稿では、複数の機能を1つのタブにまとめて表示するアプリケーションを作成してみます。

はじめに

 アプリケーションの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一覧
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」コントロールです。

[WPFコンポーネント]でアセンブリ名が「C1.WPF」の「C1TabControl」コントロールを選択する
[WPFコンポーネント]でアセンブリ名が「C1.WPF」の「C1TabControl」コントロールを選択する

C1TabControlコントロールについて

 C1TabControlコントロールは、WPF上のページに複数のタブページを提供するコンテナコントロールで、各タブページにコントロールを配置して使用します。

C1TabControlコントロールの要素

 C1TabControlコントロールは、タブ、タブストリップ、タブページで構成されています。

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>
GridやStackPanelコントロールを使って複数のコントロールをタブに配置できる(ヘルプファイルより抜粋)
GridやStackPanelコントロールを使って複数のコントロールを1つのタブページに配置できる(ヘルプファイルより抜粋)

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つ追加します。

タブページを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プロパティにはファイル名のみを格納するため、それぞれの値を変数に格納しておきます。

Visual Basic
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
C#
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プロパティに設定して表示します。

Visual Basic
        ' タブページと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
C#
        
        // タブページと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列挙体のメンバを設定します。

C1TabItemShape列挙体
メンバ名 説明
Rectangle 四角のタブ形状
Rounded 丸いタブ形状
Sloped 斜めのタブ形状
Ribbon S字型タブ

 また、タブの表示位置は、C1TabControlクラスのTabStripPlacementプロパティで設定します。設定値は、C1.WPF名前空間にあるDockクラスのメンバを指定します。

Visual Basic
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
C#
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つのコントロールで複数のタブページを使用できれば、ページエリアを有効に使うことができるとともに、多くの機能を整理して組み込むことができます。

 多機能が求められている昨今のアプリケーションでは、威力を発揮するコントロールではないでしょうか。

参考文献

  • ブックマーク
  • LINEで送る
  • このエントリーをはてなブックマークに追加

著者プロフィール

  • 瀬戸 遥(セト ハルカ)

    8ビットコンピュータの時代からBASICを使い、C言語を独習で学びWindows 3.1のフリーソフトを作成、NiftyServeのフォーラムなどで配布。Excel VBAとVisual Basic関連の解説書を中心に現在まで40冊以上の書籍を出版。近著に、「ExcelユーザーのためのAccess再...

All contents copyright © 2005-2020 Shoeisha Co., Ltd. All rights reserved. ver.1.5