はじめに
Windowsフォームにコントロールをレイアウトする際、コントロールの数が多いと配置に苦労します。また、ユーザーがコントロールのサイズを変更できるようにしたい時などは、複数のコントロールをうまく連動させるのは、かなり骨の折れる作業です。
PowerTools Sizer for Windows FormsのC1Sizerコンポーネントは、フォーム内をグリッド状に区切り、その中にコントロールを配置することができるコンテナコントロールです。グリッドの各行列の境界線をユーザーがドラッグできるように設定できるため、Webページのフレームのようにウィンドウフォームをレイアウトすることができます。
今回は、このC1Sizerコンポーネントを使い、植物の名前をクリックするとその説明文と画像を表示するアプリケーションを作成してみました。
対象読者
Visual Basic/Visual C# 2008を使ってプログラムを作ったことのある人
必要な環境
Visual Basic 2005/2008、Visual C# 2005/2008、Visual Studio 2005/2008でプログラムが作れる環境。なお、本プログラムはWindows Vista上で動作するVisual Studio 2008を使用して作成し、動作確認を行っています。
プログラム実行時の注意事項
Sizer for Windows Formsを使って作成したアプリケーションを配布する場合、Sizer for Windows Formsのアセンブリファイルを添付する必要があります。アプリケーションを正常に動作させるためには、次のファイルをインストールする必要があります。
| ファイル | 内容 |
|---|---|
| C1.Win.C1Sizer.2.dll | C1Sizer コントロール(Visual Studio 2005/2008 用) |
このファイルを、プログラムを実行するフォルダへフォルダ構成を変えずに格納します。
コンポーネントのインストール
はじめてPowerTools Sizer for Windows Formsコンポーネントを使用する方は、Visual Studio、Visual Basic、Visual C#の開発環境にComponentOne Studio Enterprise 2010Jをインストールする必要があります。
インストーラは、グレープシティのWebページからダウンロードできます。製品ページの[申込フォーム]をクリックし、グレープシティのWebサイトへ必要情報を登録すると、トライアルライセンスキーファイルとダウンロードサイトを記載したE-Mailが送られてきますので、ここからダウンロードします。制限事項などの詳細については、インストーラに同梱されているリリースノートを参照ください。
コントロールの追加
ComponentOne Studio Enterprise 2010Jをインストールしたら、ツールボックスに専用のタブを作成し、使用するコンポーネントを追加します。追加するコンポーネントは、アセンブリ名が「C1.Win.C1Sizer.2」の「C1Sizer」コントロールです。

C1Sizerコンポーネントについて
C1Sizerコンポーネントは、強力なグリッドレイアウトマネージャを持つコンテナコントロールです。C1Sizerをフォームに配置すると、コントロールの組み込みが可能なグリッドを作成することができます。
また、ユーザーが境界線をドラッグしてリサイズし、表示領域を自由に変更できるようなフォームデザインを簡単に実現できます。プログラム実行時に行列をユーザーが追加・削除できるようにすることも可能です。
各種設定を行える「グリッドエディタ」が搭載されており、行列それぞれ次のようなコマンドを使って編集することが可能です。
| コマンド | 説明 |
|---|---|
| 挿入 | 新しいバンド(※注)をコレクション内の指定された位置に挿入します。 |
| 追加 | 新しいバンドをコレクションに追加します。 |
| 削除 | 選択されたバンドを削除します。 |
| 均等 | すべてのバンドを同じサイズに設定します。 |
| クリア | すべてのバンドをクリアします。 |
| 自動 | 子コントロールに基づいてバンドを作成します。 |
| OK | 変更を更新してC1Sizerグリッドエディタを閉じます。 |
C1Sizerコンポーネントでは、グリッドの行や列を「バンド」と呼びます。


グリッドの設定プロパティ
次のプロパティを使ってグリッドのマス目を設定できます。
| プロパティ | 説明 |
|---|---|
| IsFixedSize | コントロールをリサイズするとき、バンドのサイズを固定するかどうかを指定します。デフォルトの値は、Falseです。 |
| IsSplitter | バンドがスプリッタのように動作するかどうか(実行時にマウスでリサイズできるかどうか)を指定します。デフォルトの値は、Falseです。 |
| Size | 行の高さ、または列の幅をピクセル単位で取得または設定します。 |
C1Sizerコンポーネントをフォームに配置し、Dockプロパティでフォームと一体化させると、フォームのサイズ変更に追従してC1Sizerコンポーネントのグリッドも自動的にサイズが変わります。IsFixedSizeプロパティを使えば、フォームのサイズを変えても、特定のバンドのサイズは同じ状態を保持するように設定できます。このプロパティは、グリッドのマス目1つ1つに設定することが可能です。

IsSplitterは、グリッドの境界線をプログラム実行時にユーザーが操作できるように設定するプロパティです。このプロパティも、グリッドのマス目1つ1つに設定できます。
さらに、C1Sizerコントロールは、配置した他のコントロールのサイズをグリッドと連動して変更させる機能を持っています。グリッドのマス目にコントロールを配置すると、そのコントロールはマス目と同サイズとして配置され(DockプロパティのFillと同じ状態)、グリッドのサイズを変更した場合、連動してコントロールのサイズも変化するようになります。これは、境界線を移動させても同じ動作をします。
プログラム実行時に、グリッドがあることを見せたくない場合は、C1SizerコンポーネントのBorderプロパティを「0」にすると境界線が非表示になります。
また、AutoSizeModeを「None」にすると、マス目に配置したコントロールのサイズを自由に設定できるようになり、レイアウトの自由度が上がります。


GUIの作成
このプログラムでは、フォームにC1Sizerコンポーネントを配置して1行3列のグリッドを作成し、「TreeView」「RichTextBox」「PictureBox」の3つのコントロールを配置して、境界線を移動できるように設定します(Form1)。また、画像の著作権を表示するためのメニューを1つ設定します(Form2)。

各プロパティの設定
それぞれのフォームとプロパティの設定は下記の表のとおりです。
| コントロール | プロパティ | 設定値 |
|---|---|---|
| TreeView | Nodes | (画像参照) |
| RichTextBox | ReadOnly | True |
| PictureBox | SizeMode | StretchImage |
| ToolStripMenuItem | Text | 雪割草カタログについて(A) |
| Alignment | Right |
| コントロール | プロパティ | 設定値 |
|---|---|---|
| Label | Text | (画像参照) |
| BorderStyle | Fixed3D | |
| Button | Text | OK |
RichTextBoxコントロールは説明文の表示に使用するので、ReadOnlyプロパティをTrueにし、読み出し専用に設定します。なお、C1Sizerコンポーネントの設定については後述します。TreeViewコントロールのNodesプロパティの設定は、下図を参照ください。
C1Sizerコンポーネントの設定
では、フォームをデザインしていきます。
- フォームにMenuStripコントロールを配置し、写真の著作権を表示するメニューを設定します。
- 次に、フォームにC1Sizerコンポーネントを配置します。Dockプロパティを「Fill」に設定して、フォーム全体に広げます。
- C1Sizerコンポーネントのスマートタグをクリックし、[グリッドの編集]を選択して、「C1Sizerグリッドエディタ」を起動させます。
- 「列」タブを選択して[追加]ボタンをクリックし、C1Sizerコンポーネントに3列のグリッドを作成します。
- 各列の「IsSplitter」プロパティを「True」にします。これで、グリッドの各列の境界線がドラッグ可能になります。
3列のグリッドを作成し、「IsSplitter」プロパティを「True」にする

- 列の左から順番に「TreeView」「RichTextBox」「PictureBox」の3つのコントロールをドラッグ&ドロップします。各コントロールは、それぞれの列に自動的にドッキングします。
- 各コントロールのプロパティを設定します。C1Sizerコンポーネントは、たったこれだけの設定で使うことができます。
- 著作権表示用のフォーム「Form2」は、ラベルとボタンで作成するだけです。
説明文と画像の表示処理
このプログラムでは、例えば、TreeViewコントロールのノードにある「雪割草」という山野草の品種名をクリックすると、RichTextBoxコントロールに説明文を、PictureBoxコントロールに画像を表示します。
サンプルプログラムなので、そんなに凝ったものではありませんが、説明文はrtf形式のテキストで、画像はJPEG形式のファイルでそれぞれ作成され、プログラムの実行ファイル(exeファイル)があるフォルダ内の「App_Data」というサブフォルダに格納されます。


データの読み込み処理
データと写真を読み込む処理は、TreeViewコントロールのノードがクリックされたタイミングで行います。
ノードをクリックすると、TreeViewコントロールには「AfterSelect」というイベントが発生します。このイベントハンドラの引数「e」から、クリックされたノードの文字を読み取り、どのノードがクリックされたのかを把握します。
- まず、Private変数「my_pass」を宣言し、フォームのLoadイベントハンドラでApplicationオブジェクトのStartupPathプロパティを参照して、実行プログラムのあるフォルダのディレクトリを把握します。
- 次に、TreeViewコントロールのAfterSelectイベントハンドラで、イベントが発生したNodeオブジェクトのTextプロパティを読み取り、処理を分岐します。各分岐処理では、フォルダ「App_Data」からrtfファイルとJPEGファイルを読み込んで、それぞれRichTextBoxとPictureBoxコントロールで表示します。
Public Class Form1
Private my_pass As String
Private Sub Form1_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load
my_pass = Application.StartupPath
End Sub
Private Sub TreeView1_AfterSelect(ByVal sender As System.Object, ByVal e As System.Windows.Forms.TreeViewEventArgs) Handles TreeView1.AfterSelect
Select Case e.Node.Text
Case "紅おけさ"
Me.PictureBox1.Image = Image.FromFile(my_pass & "\App_Data\beni_okesa.jpg")
Me.RichTextBox1.LoadFile(my_pass & "\App_Data\紅おけさ.rtf")
Case "川蝉"
Me.PictureBox1.Image = Image.FromFile(my_pass & "\App_Data\kawasemi.jpg")
Me.RichTextBox1.LoadFile(my_pass & "\App_Data\川蝉.rtf")
Case "麗人"
Me.PictureBox1.Image = Image.FromFile(my_pass & "\App_Data\reijin.jpg")
Me.RichTextBox1.LoadFile(my_pass & "\App_Data\麗人.rtf")
Case "深山"
Me.PictureBox1.Image = Image.FromFile(my_pass & "\App_Data\miyama.jpg")
Me.RichTextBox1.LoadFile(my_pass & "\App_Data\深山.rtf")
End Select
End Sub
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
namespace my_sizer_cs
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
private string my_pass;
private void Form1_Load(object sender, EventArgs e)
{
my_pass = Application.StartupPath;
}
private void treeView1_AfterSelect(object sender, TreeViewEventArgs e)
{
switch (e.Node.Text)
{
case "紅おけさ":
pictureBox1.Image = Image.FromFile(my_pass + "/App_Data/beni_okesa.jpg");
richTextBox1.LoadFile(my_pass + "/App_Data/紅おけさ.rtf");
break;
case "川蝉":
pictureBox1.Image = Image.FromFile(my_pass + "/App_Data/kawasemi.jpg");
richTextBox1.LoadFile(my_pass + "/App_Data/川蝉.rtf");
break;
case "麗人":
pictureBox1.Image = Image.FromFile(my_pass + "/App_Data/reijin.jpg");
richTextBox1.LoadFile(my_pass + "/App_Data/麗人.rtf");
break;
case "深山":
pictureBox1.Image = Image.FromFile(my_pass + "/App_Data/miyama.jpg");
richTextBox1.LoadFile(my_pass + "/App_Data/深山.rtf");
break;
}
}
Form2の処理
著作権表示用のフォーム「Form2」の表示は、メニュー「雪割草カタログについて」のClickイベントハンドラで行います。これは、ただ単にForm2を表示させるだけです。また、Form2の[OK]ボタンは、フォームを閉じる処理のみ行います。
Form1のコード
Private Sub 雪割草カタログについてToolStripMenuItem_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles 雪割草カタログについてToolStripMenuItem.Click
Form2.Show()
End Sub
End Class
private void 雪割草カタログについてAToolStripMenuItem_Click(object sender, EventArgs e)
{
Form2 fm2 = new Form2();
fm2.Show();
}
}
}
Form2のコード
Public Class Form2
Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
Me.Close()
End Sub
End Class
namespace my_sizer_cs
{
public partial class Form2 : Form
{
public Form2()
{
InitializeComponent();
}
private void button1_Click(object sender, EventArgs e)
{
this.Close();
}
}
}
まとめ
C1Sizerコンポーネントは、WindowsフォームをWebページのフレームのように分割してレイアウトできるコンポーネントです。
コントロールを多用するフォームのデザインでは、コントロールを並べていくだけでも結構面倒な作業ですが、C1Sizerコンポーネントを使えばグリッド形式でレイアウトでき、とても作業が楽になります。
また、行列の境界線の変更やサイズの固定化なども可能なため、プログラム実行時にレイアウトが崩れてしまうこともなく、逆に今回のプログラムのようにユーザーが自由に行列のサイズを変更可能にすることもできます。
今回のサンプルプログラムで使用している写真は、すべて「アルペンガーデン やまくさ」が所有しており、特別に許可を得て使用しています。そのため、写真を無断で転載・販売・掲載することを禁止いたします。







