SHOEISHA iD

※旧SEメンバーシップ会員の方は、同じ登録情報(メールアドレス&パスワード)でログインいただけます

CodeZine編集部では、現場で活躍するデベロッパーをスターにするためのカンファレンス「Developers Summit」や、エンジニアの生きざまをブーストするためのイベント「Developers Boost」など、さまざまなカンファレンスを企画・運営しています。

ComponentZine(CalendarGrid)(AD)

CalendarGrid for Windows Formsで、カレンダー機能のデータをプログラムから扱う

CalendarGrid for Windows Formsを活用したWindowsフォームアプリケーションの作成

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

 業務アプリケーションを作成するうえで、カレンダーやチャートといった形式で日付データを表示する機能は、表現方法次第で予想以上に工数が大きくなる機能です。そんな際に、柔軟にカスタマイズできて扱いやすいコントロールがあれば、自前では難しい機能の実現や、想定外の工数を押さえることができます。今回紹介する「CalendarGrid for Windows Forms(以下、CalendarGrid)」は、豊富な機能、柔軟なカスタマイズ、扱いやすいデータバインドの仕組みを持ったカレンダーコントロールです。

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

 CodeZineではこれまでもCalendarGridについての記事がありますが、今回はおさらいを兼ねた概要と、過去に紹介してこなかったプログラミングコードからデータをバインドする方法を紹介します。

過去記事

対象読者

 Visual Studioを利用してアプリケーションを作成した経験がある、またはC#、VisualBasicなどの.NET系言語での開発経験がある方。

必要な環境

 CalendarGridを利用するには以下の環境が必要となります。

  • Visual Studio 2010/2012/2013/2015 日本語版
  • .NET Framework 3.5 SP1/3.5 Client Profile/4/4 Client Profile/4.5/4.5.1/4.5.2/4.6

 本記事はVisual Studio 2015(Enterpriseエディション)、.NET Framework 4.6環境で画像キャプチャーの取得、動作検証を行っております。

コントロールのインストール

 CalendarGridを導入するには、製品を購入するかトライアル版を利用する方法があります。

 トライアル版の入手は以下のURLのフォームから申し込みを行います。

 製品の購入は以下のURLから手続きを行ってください。

 手続きを進めることで、CalendarGridのインストーラーがダウンロード可能になります。

 制限事項などの詳細については、インストーラーに同梱されているリリースノートを参照ください。

CalendarGridインストーラー起動画面
CalendarGridインストーラー起動画面

コントロールの配置

 インストーラーによるインストール作業が終われば、Visual StudioでCalendarGridコントロールが利用可能になります。

新しいプロジェクトの作成

 Windows フォームアプリケーションの新しいプロジェクトを作成します。

新しいプロジェクトの作成
新しいプロジェクトの作成

ツールボックスアイテムの選択

 プロジェクトの作成後、上部メニューの「ツール」から「ツールボックスアイテムの選択」をクリックします。

ツールボックスアイテムの選択
ツールボックスアイテムの選択

GcCalendarGridのチェック

 「.NET Framework コンポーネント」タブの「GcCalendarGrid」にチェックを入れ、右下の「OK」をクリックします。

GcCalendarGridのチェック
GcCalendarGridのチェック

 これでツールボックスにGcCalendarGridが追加されます。

GcCalendarGridが追加される
GcCalendarGridが追加される

GcCalendarGridの画面配置

 既存のコントロールと同様に、ツールボックスから「GcCalendarGrid」ドロップすることで画面に配置できます。

GcCalendarGridの配置
GcCalendarGridの配置

CalendarGridの特徴

Excelライクで操作しやすいデザイナ

 CalendarGridの大きな利点は、カレンダーの一日に表示するレイアウトをExcelのような操作感のデザイナで編集できる点です。

 Excelの経験があれば、複数行、複数列の表やスタイルの変更が簡単に可能で、複雑なレイアウトを作成することができます。

デザイナ
デザイナ

スタイルの切り替え

 デフォルトでは一か月分の日付を表示するカレンダーが表示されますが、これを一週間分の表示や、任意の表示に簡単に切り替えることができます。

 スタイルの切り替えは、プロパティウィンドウのCalendarViewプロパティから行うことができます。

スタイルの変更
スタイルの変更

 プロパティの右端の「...」をクリックすると「カレンダー表示形式エディタ」が起動し、表示したいスタイルを選択することができます。

カレンダー表示形式エディタ
カレンダー表示形式エディタ

 また、プログラムコードからも変更可能です。

プログラムコードからのスタイルの変更
// リストビュースタイルに変更
var view = new GrapeCity.Win.CalendarGrid.CalendarListView();

// 表示日を三日間に変更
view.DayCount = 3;

gcCalendarGrid1.CalendarView = view;

セルの豊富な形式

 カレンダーのセルにはテキスト形式はもちろん、コンボボックスやラジオボタン、画像などの様々な形式が利用可能です。

セルの形式
セルの形式

 セルの形式は各セルのCellTypeプロパティから変更可能です。

セルの形式変更
セルの形式変更

日本独自の日付表示形式にも対応

 これまでの画像でもわかる通り、セルに「大安」「仏滅」といった六曜がデフォルトで表示されるなど日本語での表示形式にも優れています。

 日付表示形式はセルのDateFormatプロパティから変更可能です。

DateFormat
DateFormat

プログラムによるデータ変更(1)

 CalendarGridコントロールの機能的な特徴と、セルの編集が容易な点を見てきました。

 続いては、プログラムから日付データを扱う場合を見ていきましょう。

各日付に対応するクラス

 カレンダーに入力した予定とその概要を、プログラムから動的に表示したいというケースを想定します。

 まず、各日付に対応するクラスを以下のように定義します。

カレンダーの一日に対応するクラス
/// <summary>
/// カレンダーの一日のデータを表すクラス
/// </summary>
public class CalendarData
{
    /// <summary>
    /// 日付
    /// </summary>
    public DateTime date { set; get; }

    /// <summary>
    /// タイトル
    /// </summary>
    public string title { set; get; }

    /// <summary>
    /// 概要
    /// </summary>
    public string description { set; get; }
}

 カレンダー上に表示する日付を表すDateTime型の変数dateと、予定名を表すtitleと予定の概要を表すdescriptionという、2つのstring型の変数があるクラスを用意します。

 descriptionは長くなることも想定して、デザイナで上下2行のセルを結合したセルを作成しておきます。

結合したセルを用意する
結合したセルを用意する

DataSourceプロパティにリストを代入する

 CalendarGridにデータを渡すにはDataSourceプロパティにデータのリストを代入します。

 画面に配置したCalendarGridコントロールは、Nameプロパティに「gcCalendarGrid1」という値が設定されているものとします。

データのリストをコントロールに渡す
// リストを作成する
List<CalendarData> dataList = new List<CalendarData>();
dataList.Add(new CalendarData() { date = new DateTime(2016, 1, 1), title = "初詣", description = "神社に行ってお参りをする。" });
dataList.Add(new CalendarData() { date = new DateTime(2016, 1, 4), title = "仕事はじめ", description = "朝10時に出社" });

// DataSourceプロパティにリストを代入する
gcCalendarGrid1.DataSource = dataList;

 続いて、CalendarDataクラスのdateプロパティがカレンダーの表示する日付に紐づくことを指定します。

dateプロパティがカレンダーの日付と対応することを指定する
// dateプロパティをカレンダーの日付に紐づける
gcCalendarGrid1.DateField = "date";

タイトルと概要を紐づける

 CalendarDataクラスの残りのプロパティtitle、descriptionもCalendarGridと紐づけます。

 CalendarGridの各日付セル内に表示するデータは、CalendarGridのTemplateプロパティのテンプレートに紐づけることで対応させることができます。

リストの項目をテンプレートに紐づける
// テンプレートにリストの項目を紐づける
var template = gcCalendarGrid1.Template;

// セルの上から2行目、左から0列目にtitleプロパティの値を表示する
template.Content[1, 0].DataField = "title";

// セルの上から3行目、左から0列目にdescriptionプロパティの値を表示する
template.Content[2, 0].DataField = "description";

プログラムによるデータ変更(2)

複数行表示を行う

 descriptionの値は文字数が多くなるので、セルの幅を超えた場合は折り返し表示します。

セルを折り返し対応させる
// descriptionは折り返し表示できるように
var cellType = new GrapeCity.Win.CalendarGrid.CalendarTextBoxCellType();
cellType.Multiline = true;
template.Content[2, 0].CellType = cellType;

 テキストボックスのセルを折り返し対応させる場合は、Multilineプロパティをtrueにします。

 これでカレンダーのデータを動的に設定できました。プログラムでの編集が終了したらEndEditメソッドを呼び出します。

CalendarGridにリストを表示する処理全文
private void Form1_Load(object sender, EventArgs e)
{
    List<CalendarData> dataList = new List<CalendarData>();
    dataList.Add(new CalendarData() { date = new DateTime(2016, 1, 1), title = "初詣", description = "神社に行ってお参りをする。" });
    dataList.Add(new CalendarData() { date = new DateTime(2016, 1, 4), title = "仕事はじめ", description = "朝10時に出社" });

    // データソースとCalendarGridの日付を関連付ける
    gcCalendarGrid1.DataSource = dataList;
    gcCalendarGrid1.DateField = "date";

    // テンプレートにリストの項目を紐づける
    var template = gcCalendarGrid1.Template;

    // セルの上から2行目、左から0列目にtitleプロパティの値を表示する
    template.Content[1, 0].DataField = "title";

    // セルの上から3行目、左から0列目にdescriptionプロパティの値を表示する
    template.Content[2, 0].DataField = "description";

    // descriptionは折り返し表示できるように
    var cellType = new GrapeCity.Win.CalendarGrid.CalendarTextBoxCellType();
    cellType.Multiline = true;
    template.Content[2, 0].CellType = cellType;

    // カレンダーに表示する最初の日付を設定する
    gcCalendarGrid1.FirstDateInView = new DateTime(2016, 1, 1);

    // 編集の終了を通知
    gcCalendarGrid1.EndEdit();
}

 アプリケーションを実行すると以下のように元日と4日の予定が表示されます。

実行結果
実行結果

実行画面での編集に対応する

 画面に予定を表示することができました。今度はアプリケーションの画面から新規に予定を追加された際にプログラム上のデータも変更されるようにします。

 現段階で予定を追加すると以下のようなエラーが発生します。

エラー
エラー

 これはDataSourceプロパティに渡したリスト(List<CalendarData>)がIBindingListインターフェイスを実装していないためです。IBindingListを自前で実装することも可能ですが、今回は実装済みのBindingListクラスに置き換えることにします。

 List<CalendarData>の部分を以下のように書き換えます。

CalendarGridにリストを表示する処理全文
BindingList<CalendarData> dataList = new BindingList<CalendarData>();

 これで、画面上で予定を追加した際に、プログラム側も変更されるようになりました。

新しい予定を画面から追加する
新しい予定を画面から追加する
データも変更される
データも変更される

スタイルを変えても同じデータが使える

 日付セルの項目を変えないかぎり、スタイルを変更してもバインドはそのまま動作します。

スタイルを変えてもコードは変更不要
スタイルを変えてもコードは変更不要

 これはCalendarGridの扱いやすさを表すと同時に、同社の同様の操作性を持つ「MultiRow for Windows Forms」や「SPREAD for Windows Forms」と組み合わせてより幅が広い画面表現が可能であることを示しています。

ガントチャート風のバーの追加

 CalendarGridは、予定が複数日にまたがる場合などにガントチャート表現で表すことができます。

ガントチャート表示
ガントチャート表示

 上記画像のようにバーを表示し、複数日にまたがる場合はバーを期間分表示するようにプログラムを変更します。

CalendarDataクラスの変更

 CalendarDataクラスに以下のように期間を表すプロパティを追加します。

CalendarDataに期間を表すプロパティを追加
/// <summary>
/// カレンダーの一日に対応するクラス
/// </summary>
public class CalendarData
{
    /// <summary>
    /// 日付
    /// </summary>
    public DateTime date { set; get; }

    /// <summary>
    /// タイトル
    /// </summary>
    public string title { set; get; }

    /// <summary>
    /// 概要
    /// </summary>
    public string description { set; get; }

    /// <summary>
    /// 予定の期間
    /// </summary>
    public int span { set; get; }
}

予定の追加

 予定として3日間にまたがる「出張」を追加します。

セルのタイプを変更する
BindingList<CalendarData> dataList = new BindingList<CalendarData>();
dataList.Add(new CalendarData() { date = new DateTime(2016, 1, 1), title = "初詣", description = "神社に行ってお参りをする。", span = 1 });
dataList.Add(new CalendarData() { date = new DateTime(2016, 1, 4), title = "仕事はじめ", description = "朝10時に出社", span = 1 });
dataList.Add(new CalendarData() { date = new DateTime(2016, 1, 6), title = "出張", description = "香港に出張", span = 3 });

 最後の行の「出張」だけ、spanプロパティに3の値を設定しています。

セルのタイプを変更する

 タイトルを表示していたセルをガントチャートのバーが表示できるAppointmentCellTypeに変更します。

 この処理はデザイナーを用いて行うこともできますが、ここではプログラムコードから行います。

セルのタイプを変更する
// セルの上から2行目、左から0列目にtitleプロパティの値を表示する
template.Content[1, 0].DataField = "title";

// セルに名前をつける(後で利用するため)
template.Content[1, 0].Name = "Appoint";

// セルのタイプをAppointmentCellTypeに変更する
template.Content[1, 0].CellType = new GrapeCity.Win.CalendarGrid.CalendarAppointmentCellType();

予定の期間をカレンダーに設定する

 最後に、期間をカレンダーに反映させます。ここで先ほど設定したテンプレートのNameの値"Appoint"を利用します。

カレンダーに期間を反映させる
// 期間の設定をする
foreach (var tmpData in dataList)
{
    gcCalendarGrid1[tmpData.date]["Appoint"].ColumnSpan = tmpData.span;
}

 ガントチャートの期間はセルのColumnSpanプロパティを利用して表現します。

 ここまでの全文は以下です。

カレンダーに期間を反映させる
private void Form1_Load(object sender, EventArgs e)
{
    BindingList<CalendarData> dataList = new BindingList<CalendarData>();
    dataList.Add(new CalendarData() { date = new DateTime(2016, 1, 1), title = "初詣", description = "神社に行ってお参りをする。", span = 1 });
    dataList.Add(new CalendarData() { date = new DateTime(2016, 1, 4), title = "仕事はじめ", description = "朝10時に出社", span = 1 });
    dataList.Add(new CalendarData() { date = new DateTime(2016, 1, 6), title = "出張", description = "香港に出張", span = 3 });

    // データソースとCalendarGridの日付を関連付ける
    gcCalendarGrid1.DataSource = dataList;
    gcCalendarGrid1.DateField = "date";

    // テンプレートにリストの項目を紐づける
    var template = gcCalendarGrid1.Template;

    // セルの上から2行目、左から0列目にtitleプロパティの値を表示する
    template.Content[1, 0].DataField = "title";

    // セルに名前をつける(後で利用するため)
    template.Content[1, 0].Name = "Appoint";

    // セルのタイプをAppointmentCellTypeに変更する
    template.Content[1, 0].CellType = new GrapeCity.Win.CalendarGrid.CalendarAppointmentCellType();

    // セルの上から3行目、左から0列目にdescriptionプロパティの値を表示する
    template.Content[2, 0].DataField = "description";

    // descriptionは折り返し表示できるように
    var cellType = new GrapeCity.Win.CalendarGrid.CalendarTextBoxCellType();
    cellType.Multiline = true;
    template.Content[2, 0].CellType = cellType;

    // 期間の設定をする
    foreach (var tmpData in dataList)
    {
        gcCalendarGrid1[tmpData.date]["Appoint"].ColumnSpan = tmpData.span;
    }

    // カレンダーに表示する最初の日付を設定する
    gcCalendarGrid1.FirstDateInView = new DateTime(2016, 1, 1);

    var date = dataList[0].date;

    // 編集の終了を通知
    gcCalendarGrid1.EndEdit();
}

 これで複数日にまたがる予定にバーを表示できます。

 注意したい点は、一つの行ではバーを重ねることができないことです。同日に複数のバーが重なる場合は、その分の行が必要になります。

同日に複数の予定が存在する場合
同日に複数の予定が存在する場合

まとめ

 CalendarGridの優れたデザイナ機能や、プログラムコードによるバインドを紹介しました。これらの機能により、複雑なセル構成のカレンダー画面を容易に作成することができます。また以下に紹介するように公式のドキュメントもわかりやすいため、業務アプリケーションの要求に合わせた機能が実現可能かの判断が行いやすいのも嬉しいポイントです。

この記事は参考になりましたか?

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

【AD】本記事の内容は記事掲載開始時点のものです 企画・制作 株式会社翔泳社

この記事は参考になりましたか?

この記事をシェア

  • このエントリーをはてなブックマークに追加
CodeZine(コードジン)
https://codezine.jp/article/detail/9190 2016/02/03 11:45

イベント

CodeZine編集部では、現場で活躍するデベロッパーをスターにするためのカンファレンス「Developers Summit」や、エンジニアの生きざまをブーストするためのイベント「Developers Boost」など、さまざまなカンファレンスを企画・運営しています。

新規会員登録無料のご案内

  • ・全ての過去記事が閲覧できます
  • ・会員限定メルマガを受信できます

メールバックナンバー

アクセスランキング

アクセスランキング