はじめに
前回の記事『スペルチェック機能を持ったワープロ風WPFアプリケーションの作成』で作成したアプリケーションには、文書の保存・読み込み機能がありません。
そこで今回は、この機能を追加しツールバーで操作できるようにし、より実用性のあるアプリケーションに仕上げてみました。
対象読者
Visual Basic 2010/2012、またはVisual C# 2010/2012を使ってプログラムを作ったことがある人。
必要な環境
Visual Basic 2010/2012、Visual C# 2010/2012、Visual Studio 2010/2012、SQL Server Expressでプログラムが作れる環境。
なお、本プログラムは次の環境で開発・動作確認を行っています。
- OS:Windows 7
- 開発Tool:Visual Studio 2010、.NET Framework 4
プログラム実行時の注意事項
本稿の実行ファイル(バイナリファイル)を動かすには、zipファイルに同梱してある以下のファイルが必要になります(.NET Framework 4でのみご使用いただけます)。
ファイル名 | 説明 |
---|---|
C1.WPF.4 | 本体アセンブリ |
C1.WPF.RichTextBox.4 | 本体アセンブリ |
C1.WPF.RichTextBox.Toolbar.4 | 本体アセンブリ |
C1.WPF.SpellChecker.4 | 本体アセンブリ |
C1Spell_en-US.dct | 辞書ファイル(英語版) |
C1.WPF.Toolbar.4 | 本体アセンブリ(今回追加) |
このファイルを、実行プログラムと同じフォルダに格納します。
コンポーネントのインストール
トライアル版は、グレープシティのWebページから申し込みできます。
トライアル申込フォームが表示されますので、必要情報を入力して申し込むとトライアル版のダウンロード手順を記載したE-Mailが送られてきます。その手順にそってダウンロードを行ってください。また、ダウンロードファイルは圧縮ファイルになっていますので、解凍してインストーラを起動します。
制限事項などの詳細については、インストーラに同梱されているリリースノートを参照ください。
コントロールと参照の追加
ComponentOne Studio 2013Jをインストールしたら、プロジェクトにコントロールを追加します。
ツールボックスに専用のタブを作成し、使用するコンポーネントを追加します。
追加するコンポーネントは、アセンブリ名が「C1.WPF.Toolbar.4」の「C1Toolbar」コントロールです。
このコントロールを追加すると、プロジェクトに以下のランタイムライブラリへの参照が追加されます。.NET Framework 4が必要です。
ファイル名 | 内容 |
---|---|
C1.WPF.Toolbar.4 | 本体アセンブリ |
これで、前回追加した参照設定を含め、全部で5つの参照がプロジェクトに追加されます。

C1Toolbarコントロールの概要
今回のアプリケーションでは、リッチテキストボックスに入力したデータをファイルに保存したり、ファイルから読み込む機能を追加します。
そして、この機能をツールバーで操作できるように、カスタムツールバーを作成し実装します。
このツールバーは、Toolbar for WPFのC1Toolbarコントロールを使用します。
このコントロールは、アプリケーションにナビゲーション機能を追加するためのカスタムツールバーを作成するコントロールです。ツールバーにリンクやカスタムコンテンツ、セパレータ、グループなどを組み込むことができ、またほとんどすべての種類のコントロールを配置できます。
このコントロールは、次のような主要機能を持っています。
タブとグループ
タブやグループを使用して、関連するコマンドをまとめて整理できます。例えば、関連するツールバーボタン同士を「フォント」や「クリップボード」などのグループにまとめることができます。タブやグループには、それに含まれるコマンドやアクションを表すラベルを付けることが可能です。
リボンに似た機能
C1Toolbarには、折りたたみ、ヘルプ、ダイアログランチャーのボタンなど、MicrosoftのRibbonに似た機能が組み込まれています。
軽量のToolbarStrip
簡単なシナリオで軽量のC1ToolbarStripを作成できます。
スタイルが設定されたボタンおよびドロップダウン
C1ToolBarコントロールは、任意のUIElementをサポートするコンテナです。ツールバーを簡単に作成できるように、Toolbar for WPFには、ボタン、トグルボタン、セパレータ、ドロップダウンコントロールなど、ツールバーに配置できるさまざまなコントロールが用意されています。イベントハンドラをアタッチしたり、コマンドフレームワークを活用して、各コントロールに動作を追加できます。
WPFコマンドフレームワークのサポート
ツールバーは、WPFコマンドフレームワークをサポートします。それぞれタイトルと小さな/大きな画像ソースを含むコマンド群を一度作成し、それらを複数のツールバーで共有できます。
オーバーフローのサポート
ストリップパネルの空きスペースに応じて、ストリップパネルとドロップダウンオーバーフローパネルの間で項目が入れ替わります。デフォルトでは自動的に入れ替わりますが、必要に応じていつでも無効に設定できます。
方向の変更
ツールバーの方向を水平(デフォルト)と垂直から選択します。
ClearStyle技術のサポート
Toolbar for WPFは、コントロールのテンプレートを変更することなくコントロールの色を簡単に変更できるComponentOneの新しいClearStyle技術をサポートします。色のプロパティをいくつか設定するだけで、C1Toolbar要素のスタイルを簡単に設定できます。
C1ToolBarコントロールの要素
C1Toolbarコントロールは、他のコントロール(ボタン、チェックボタン、テキストボックス、ドロップダウンリスト、分割ボタン、セパレータなど)を保持するためのコンテナとして使用されます。
C1ToolBarコントロールは、ツールバーに組み込むコントロールを以下の7つのオブジェクトによってサポートします。
オブジェクト | 機能 |
---|---|
C1ToolbarGroup | ツールバーグループ |
C1ToolbarButton | ツールバーボタン |
C1ToolbarDropDown | ツールバードロップダウン |
C1ToolbarSplitButton | ツールバー分割ボタン |
C1ToolbarStrip | ツールバーストリップ |
C1ToolbarTabItem | ツールバータブ項目 |
C1ToolbarToggleButton | ツールバートグルボタン |
ツールバーグループ
C1ToolBarGroupオブジェクトは、ツールバー内にグループを定義します。グループには、C1ToolbarButton、C1ToolbarToggleButton、C1ToolbarDropDown、C1ToolbarSplitButtonの各ツールバーコントロールを組み込むことが可能です。
グループにツールバー項目を追加すると、四角形のボックス内に子のツールバー項目がまとめて表示されます。
そして、グループ内に配置した各コントロールは、一度に1つの機能のみを使用することができます。
また、GroupSizeDefinitionプロパティを使って、グループ内のコントロールのサイズ(大、中、小)とボタンテキストの位置を定義します。
例えば"大"を使用すると、グループ内のコントロールがLargeImageResourceプロパティに設定された画像サイズを取得し、LabelTitleプロパティのテキスト値を画像の下に配置します。
"小"を使用すると、画像だけを表示しテキストは表示しません。
グループは、Headerプロパティを使ってラベルを表示できます。
<c1:C1Toolbar Name="C1Toolbar1"> <c1:C1ToolbarGroup Header="ファイル" Width="130" Height="120"> </c1:C1ToolbarGroup> </c1:C1Toolbar>

ツールバーボタン
C1ToolBarButtonオブジェクトは、ツールバーボタンを定義します。ボタンには、テキスト、画像、またはテキストと画像の両方を含めることが可能です。
LabelTitleプロパティを使用してテキストを設定し、LargeImageSource/SmallImageSourceプロパティを使用して画像を設定します。
ボタンは、設計時にC1ToolbarItemsコレクションエディタを使用して追加するか、C1ToolBarItemCollectionコレクションのC1ToolBarItemCollection.AddまたはC1ToolBarItemCollection.Removeメソッドを使用してプログラムで追加するか、XAMLコードを使用して追加することができます。
XAMLでグループ内にボタンを配置するには、<c1:C1ToolbarGroup>要素の中に記述します。
<c1:C1Toolbar Name="C1Toolbar1"> <c1:C1ToolbarGroup Header="ファイル" Width="130" Height="120"> <c1:C1ToolbarButton LabelTitle="開く" LargeImageSource="/Images/openfolderHS.png" Width="50" Margin="0,10,0,0" Name="button1"/> <c1:C1ToolbarButton LabelTitle="保存" SmallImageSource="/Images/saveHS.png" Name="button2" Width="50" /> </c1:C1ToolbarGroup> </c1:C1Toolbar>
ツールバードロップダウン
C1ToolbarDropDownコントロールは、C1ToolbarStripコントロール上のドロップダウンボタンを表します。これをクリックすると、Contentプロパティを含むポップアップパネルまたはMenuプロパティによって設定されたコンテキストメニューが表示されます。
ドロップダウンボタンをクリックすると、Clickイベントが常に発生しドロップダウンリストが表示されます。

ツールバー分割ボタン
C1ToolbarSplitButtonコントロールは、C1ToobarStripコントロール上のドロップダウン分割ボタンを表します。
このコントロールは、C1ToolbarDropDownコントロールに似ていますが、ボタン領域と下向き矢印という2つのクリック可能な領域が含まれます。
右端にある下向き矢印が付いた四角形の部分をクリックすると、Contentプロパティを含むポップアップパネルまたはContextMenuプロパティによって設定されたコンテキストメニューが表示されます。
ボタンの左側をクリックすると、標準のボタンと同様にClickイベントが発生します。通常は、Clickイベントを使用してデフォルトのアクションまたは最後のアクションを実行しますが、ポップアップを使用して別のオプションを選択することも可能です。
ボタンの上にカーソルを合わせると、ボタン領域とドロップダウン矢印を分けるための縦線が表示されます。

ツールバーストリップ
C1ToolbarStripコントロールは、ツールバーコントロールやその他のC1 WPFコントロールのコンテナになります。
C1ToolbarStripコントロールには、C1ToolbarButton、C1ToolbarToggleButton、C1ToolbarDropDown、C1ToolbarSplitButton、C1Separator、C1ComboBox、およびC1TextBoxコントロールを組み込むことができます。
C1ToolbarStripコントロールは、ストリップパネル内のスペースに応じて、オーバーフローをサポートします。パネル内の各項目は、ストリップパネルとドロップダウンオーバーフローパネルの間を移動します。デフォルトでは自動的に行われますが、無効にしたり、常時有効にしたり、必要時に有効にすることも可能です。

ツールバータブ項目
C1ToolbarTablItemコントロールは、C1Toolbarコントロール内にタブ項目を組み込みます。このコントロールは、小さなウィンドウスペースに大量の情報を表示する場合に使用すると効果的です。
C1ToolbarTabItemコントロールは、いくつかのコントロールを1つのページにまとめ、一度に1つのタブを表示します。
タブ内に複数のグループを作成できるので、アプリケーションの機能を操作するコントロールを、グループごとにタブでまとめることが可能です。

ツールバートグルボタン
C1ToolbarToggleButtonコントロールは、C1ToolbarToolStripコントロール上のトグルボタンを表します。
トグルボタンは状態を持つボタンで、ユーザーがオンとオフの状態を切り替えることができます。トグルボタンをクリックすると、もう一度クリックするまで、ボタンは有効状態、つまり押されたままになります。
トグルボタンは、ボタンと同様に画像とテキストを表示できますが、ボタンがクリックされ有効状態になったことを示すために、PressedBrushプロパティで色を設定できます。

GUIの作成
では、さっそくアプリケーションを作成していきましょう。
今回作成するアプリケーションは、前回作成したアプリケーションにC1Toolbarコントロールを追加し、1つのグループ「ファイル」と2つのボタン「保存」「開く」を配置します。
ウィンドウ内に3つのコントロールを配置するため、スタックパネルではなく2行2列のグリッドを用いてコントロールをレイアウトします。
ツールバーの作成
今組み込んであるリッチテキストボックスツールバーの横にC1Toolbarコントロールを追加し、ファイル操作用のツールバーを作成します。
そのために、C1RichTextBoxToolbarコントロールとC1RichTextBoxコントロールをスタックパネルでレイアウトしているのを、2行2列のグリッドを使ったレイアウトに変更します。
① グリッドは、RowDefinition・ColumnDefinition要素をそれぞれ2つずつ作成し、1行目1列目にC1Toolbarコントロールを、1行目2列目にC1RichTextBoxToolbarコントロールを、2行目1列目にC1RichTextBoxコントロールをレイアウトするように、XAMLを書き換えます。
なお、今回はウィンドウのリサイズ処理は使わないようにしますので、グリッドのサイズは1行目だけ指定し、リッチテキストボックスのサイズ指定も削除します。
<Grid> <StackPanel Height="465" HorizontalAlignment="Left" Name="StackPanel1" VerticalAlignment="Top" Width="665"> <c1:C1RichTextBoxToolbar Name="c1RichTextBoxToolbar1" RichTextBox="{Binding ElementName= c1RichTextBox1}"/> <c1:C1RichTextBox Name="c1RichTextBox1" Height="343" Width="665" /> </StackPanel> </Grid>
<Grid Name="Grid1" HorizontalAlignment="Left" > <Grid.RowDefinitions > <RowDefinition Height="125"/> <RowDefinition /> </Grid.RowDefinitions> <Grid.ColumnDefinitions> <ColumnDefinition Width="133*" /> <ColumnDefinition /> </Grid.ColumnDefinitions> <c1:C1RichTextBoxToolbar Grid.Column="1" Name="C1RichTextBoxToolbar1" RichTextBox="{Binding ElementName= C1RichTextBox1}" /> <c1:C1RichTextBox Name="C1RichTextBox1" Grid.ColumnSpan="2" Grid.Row="1" /> </Grid>
② ツールボックスから、C1Toolbarコントロールをグリッドにドラッグ&ドロップし、グリッドの枠内に収まるようにします。
③ XAML画面を表示し、グループ「ファイル」を作成します。
<c1:C1Toolbar Height="125" HorizontalAlignment="Left" Name="c1Toolbar1" VerticalAlignment="Top" Width="131"> <c1:C1ToolbarGroup Header="ファイル" Width="130" Height="120" > </c1:C1ToolbarGroup> </c1:C1Toolbar>

④ ツールボックスから、C1ToolbarButtonコントロールを2つ、グループ内にドラッグ&ドロップし、Nameプロパティを「Button1」「Button2」に変更します。

⑤ プロジェクトにフォルダ「images」を作成し、アイコン画像を2つ追加する。

⑥ ボタンのLargeImageSource、SmallImageSource、LabelTitleプロパティを使用して、テキストと画像を組み込みます。
また、Contentsプロパティの値を削除し、Button1のみMarginプロパティを設定します。これで、2つのボタンにテキストと画像が表示されます。
なお、LargeImageSource、SmallImageSourceプロパティに設定する画像のパス名は「/image」から始まるように修正しておきます。
また、実行ファイルを直接起動する場合は、実行ファイルのあるフォルダ内にこのimagesフォルダをコピーしておいてください。
<c1:C1ToolbarGroup Header="ファイル" Width="130" Height="120"> <c1:C1ToolbarButton LabelTitle="開く" Width="50" LargeImageSource="/images/openfolderHS.png" Margin="0,10,0,0" Name="Button1" /> <c1:C1ToolbarButton LabelTitle="保存" Width="50" SmallImageSource="/images/saveHS.png" Name="Button2" /> </c1:C1ToolbarGroup>

⑦ 2つのボタンのClickイベントハンドラを作成します。
⑧ 最後に、C1RichTextBoxコントロールのHorizontalScrollBarVisibilityプロパティを"Auto"にします。これで、リッチテキストボックス内のコンテンツがリッチテキストボックスの高さを超えると、自動的に垂直スクロールバーが表示されます。
ファイルの保存・読み出し処理
GUIが出来上がりましたので、ビハインドコードでファイルの保存・読み出し処理を作成します。この処理は、System.IO名前空間にあるFileクラスを使用します。
C1RichTextBoxコントロールは、入力されたデータをHTML形式で保存します。こうすると、文字の属性や画像などのデータも一緒に保存されます。
このデータは、C1RichTextBoxコントロールのHTMLプロパティに格納されます。データを表示する場合もこのHTMLプロパティに設定します。
① 最初にSystem.IO名前空間への参照を設定します。
Imports System.IO Class MainWindow Public Sub New() InitializeComponent()
using System.IO; namespace RichTB_WPF_cs { /// <summary> /// MainWindow.xaml の相互作用ロジック /// </summary> public partial class MainWindow : Window { public MainWindow() { InitializeComponent();
② 次に、ファイルに保存する処理をButton1のClickイベントハンドラに作成します。
この処理は、まずファイルを保存するダイアログボックスを表示して保存するファイル名を取得し、FileクラスのWriteAllTextメソッドを使って書き込みます。
Private Sub Button2_Click(sender As System.Object, e As System.Windows.RoutedEventArgs) Handles Button2.Click Dim dlg As New Microsoft.Win32.SaveFileDialog() Dim filename As String = "" dlg.FileName = "HTMLファイル" ' Default file name dlg.DefaultExt = ".html" ' Default file extension dlg.Filter = "HTMLファイル (.html)|*.html" ' Filter files by extension Dim result As Boolean = dlg.ShowDialog() If result = True Then filename = dlg.FileName File.WriteAllText(filename, C1RichTextBox1.Html) End If End Sub
private void Button2_Click(object sender, RoutedEventArgs e) { Microsoft.Win32.SaveFileDialog dlg = new Microsoft.Win32.SaveFileDialog(); String filename = ""; dlg.FileName = "HTMLファイル"; //Default file name dlg.DefaultExt = ".html"; // Default file extension dlg.Filter = "HTMLファイル (.html)|*.html"; // Filter files by extension bool? result = dlg.ShowDialog(); if (result == true) { filename = dlg.FileName; File.WriteAllText(filename, C1RichTextBox1.Html); } }
③ ファイルを開く処理を、Button2のClickイベントハンドラに作成します。
この処理も、ファイルを開くダイアログボックスを表示してファイル名を取得し、FileクラスのReadAllTextメソッドで読み出し、C1RichTextBoxコントロールのHTMLプロパティに設定します。
Private Sub Button1_Click(sender As System.Object, e As System.Windows.RoutedEventArgs) Handles Button1.Click Dim dlg As New Microsoft.Win32.OpenFileDialog() Dim filename As String = "" Dim data As String = "" dlg.FileName = "HTMLファイル" ' Default file name dlg.DefaultExt = ".html" ' Default file extension dlg.Filter = "HTMLファイル (.html)|*.html" ' Filter files by extension Dim result As Boolean = dlg.ShowDialog() If result = True Then filename = dlg.FileName data = File.ReadAllText(filename) C1RichTextBox1.Html = data End If End Sub
private void Button1_Click(object sender, RoutedEventArgs e) { Microsoft.Win32.OpenFileDialog dlg = new Microsoft.Win32.OpenFileDialog(); String filename = ""; String data = ""; dlg.FileName = "HTMLファイル"; // Default file name dlg.DefaultExt = ".html"; // Default file extension dlg.Filter = "HTMLファイル (.html)|*.html"; // Filter files by extension bool? result = dlg.ShowDialog(); if (result == true) { filename = dlg.FileName; data = File.ReadAllText(filename); C1RichTextBox1.Html = data; } }
ウィンドウリサイズ処理の削除
最後に、ウィンドウをリサイズした時のリッチテキストボックスのサイズ調節の処理を削除します。
前回までのアプリケーションでは、ウィンドウのリサイズ処理をウィンドウのSizeChangedイベントハンドラで行っていましたが、グリッドの自動リサイズ機能を使えばこのようなイベント処理は必要ないため、SizeChangedイベントハンドラのコードはすべて削除します。
また、VBのみ<Window>要素にある「SizeChanged="Window1_SizeChanged"」を削除します。
すでに、グリッドの2行目にあたる<Grid.RowDefinitions >要素と<Grid.ColumnDefinitions>要素ではサイズの指定は行っておらず、C1RichTextBoxコントロールのサイズ指定のプロパティは削除してあります。こうしておけば、ウィンドウをリサイズした時に、C1RichTextBoxコントロールのサイズはウィンドウのサイズに合わせて自動的に調節されます。
削除するコード
Private Sub Window1_SizeChanged(sender As System.Object, e As System.Windows.SizeChangedEventArgs) Handles MyBase.SizeChanged Grid1.Width = Window1.Width C1RichTextBox1.Width = Grid1.Width - 20 C1RichTextBoxToolbar1.Width = Grid1.Width Dim ht As New GridLength(Window1.Height - Grid1.RowDefinitions(0).Height.Value) Grid1.RowDefinitions(1).Height = ht C1RichTextBox1.Height = ht.Value - 40 End Sub
private void Window1_SizeChanged(object sender, SizeChangedEventArgs e) { Grid1.Width = Window1.Width; C1RichTextBox1.Width = Grid1.Width - 20; C1RichTextBoxToolbar1.Width = Grid1.Width; GridLength ht = new GridLength(Window1.Height - Grid1.RowDefinitions[0].Height.Value); Grid1.RowDefinitions[1].Height = ht; C1RichTextBox1.Height = ht.Value - 40; }
まとめ
C1Toolbarコントロールを使うと、WPFアプリケーションに独自のツールバーを組み込むことができます。
ツールバーは、タブやグループを利用することで、Microsoft Officeアプリケーションにあるリボン風のツールバーに仕上げることが可能です。