はじめに
前回の記事『独自の入力グリッドを持ったWPFアプリケーションの作成』では、ComponentOne Studio Enterprise 2011J(または、ComponentOne Studio for WPF 2011J)のFlexGrid for WPFに含まれるC1FlexGridコントロールをとりあげ、非連結モードでデータを入出力する方法を紹介しました。
C1FlexGridコントロールは、データを連結モードで接続すると、列ヘッダでデータをソートしたり、同じ種類のデータをグループ化するなどの機能が使えるようになります。これらの機能は、あらかじめC1FlexGridコントロールに組み込まれているので、何もしない、または簡単なコーディングですぐに使えるようになっています。
今回は、SQL ServerのデータベースファイルをC1FlexGridに連結して複数のテーブルからデータを抽出し、結果を表示するアプリケーションを作成します。
対象読者
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.FlexGrid」の「C1FlexGrid」です。
C1FlexGridコントロールについて
C1FlexGridコントロールの概要は、前回の記事『独自の入力グリッドを持ったWPFアプリケーションの作成』を参照ください。ここでは、今回使用するC1FlexGridコントロールの連結モードについて説明しておきます。
C1FlexGridコントロールの連結モード
C1FlexGridコントロールは、ItemsSourceプロパティを使ってデータをグリッドに挿入します。このItemsSourceプロパティは、IEnumerableインターフェイスを実装するオブジェクトを設定するようになっていますが、ほとんどの場合はこれより少し高いレベルで作業を行わせるため、ICollectionViewインターフェイスを実装するオブジェクトを使用します。
ICollectionViewインターフェイスは、WPFの主要なデータ連結インターフェイスで、WindowsフォームではIBindlingListインターフェイスがこの役割を果たしていました。このインターフェイスは豊富な機能を備えており、データを連結するだけでなく、データの並び変え(ソート)や特定のデータだけを表示するフィルタ機能、データのページング/グループ化などの機能も提供します。
そして、このICollectionViewインターフェイスを実装するためのクラス「ListCollectionView」が用意されています。ListCollectionViewクラスを使ってデータをC1FlexGridコントロールに設定すると、特に難しいコードを書かなくてもデータの並び変え(ソート)や特定のデータだけを表示するフィルタ機能、データのページング/グループ化などの機能を使うことができるようになります。
連結モードでのデータ連結は、次の手順を取ります。
- データをIListクラスのオブジェクトに設定
- IListオブジェクトをもとにListCollectionViewクラスのインスタンスを作成
- ItemSourceプロパティにListCollectionViewクラスのインスタンスを設定
たったこれだけの作業で、データをC1FlexGridコントロールに連結モードで連結させることができます。
データの並び変え
ICollectionViewインターフェイスを使うことで、C1FlexGridコントロールはソートをサポートします。列ヘッダをクリックすると、データは昇順または降順でソートされます。グリッドをソートすると、対応する列に現在のソート方向を示す三角形が表示されます。
C1FlexGridでは、一般的なソート切り替え動作に加え、[Ctrl]キーを押しながら列ヘッダをクリックすることでソートを解除できます。これにより、列に適用されているソートは解除され、データは元の順序で表示されます。
実際のソート処理は、データソースとして使用されるICollectionViewインターフェイスによって実行されます。C1FlexGridコントロールは単にマウスクリックを検出するだけであり、ソート処理はこのデータソースオブジェクトに任されます。
データのグループ化
ICollectionViewインターフェイスではグループ化がサポートされており、データを簡単に階層化して表示できます。例えば次のコードは、列「CategoryName」にある同じカテゴリ名のデータを1つに集約しグループ化します。
view.GroupDescriptions.Add(New PropertyGroupDescription("CategoryName"))
各データグループにはグループ名と[▲]のボタンが付き、このボタンを使ってユーザーはグループデータをマウス1つで折りたたみ/展開ができます。
アプリケーションの作成とデータベースファイルの組み込み
では、アプリケーションを作成していきましょう。使用するコントロールは、C1FlexGrid、TextBlock、CheckBoxの3つだけです。
GUIのデザイン
Gridを3行に分割し、それぞれコントロールを配置していきます。TextBlockコントロールはページの見出しに使用します。ドロップシャドウをつけて見栄えを良くします。
C1FlexGridコントロールは、サイズを決め枠線を表示するだけであとは何もしません。列見出しやデータ用セルの作成は、データを連結した時点で自動的に行われます。チェックボックスは、グループ化のオンオフに使用するので、Checked/Uncheckedイベントハンドラを作成しておきます。
なお、C1FlexGridコントロールへのデータ連結をWindowオブジェクトの初期化イベントで実行するので、次の手順で[Loaded]イベントハンドラを作成しておいてください。
-
デザイナでWindowをクリックし、プロパティウィンドウの[イベント]をクリック
-
イベントリストから[Loaded]をクリック
<Window x:Class="WPF_FG_Data_cs.MainWindow" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" Title="MainWindow" Height="500" Width="800" xmlns:c1="http://schemas.componentone.com/winfx/2006/xaml" Loaded="Window_Loaded"> <Grid Height="449" Width="769"> <Grid.RowDefinitions> <RowDefinition Height="59*" /> <RowDefinition Height="290*" /> <RowDefinition Height="100*" /> </Grid.RowDefinitions> <TextBlock Grid.Row="0" Height="31" Name="TextBlock1" Text="SQL Server データをFlexGridで表示する" Width="394" FontSize="20" Foreground="Brown"> <TextBlock.Effect> <DropShadowEffect BlurRadius="5" Color="#C3000000" /> </TextBlock.Effect> </TextBlock> <c1:C1FlexGrid Grid.Row="1" Margin="43,13,38,34" Name="C1FlexGrid1" Width="688" BorderBrush="Blue" BorderThickness="2" /> <CheckBox Content="カテゴリ名でグループ化" Grid.Row="2" Height="16" HorizontalAlignment="Left" Margin="43,11,0,0" Name="CheckBox1" VerticalAlignment="Top" Checked="CheckBox1_Checked" Unchecked="CheckBox1_Unchecked" /> </Grid> </Window>
データベースファイルのプロジェクトへの組み込み
GUIがデザインできたら、使用するデータベースをプロジェクトに組み込みます。使用するデータベースファイルは、SQL Serverのサンプルデータベース「AdventureWorksLT2008_Data.mdf」内に複数のテーブルで構成されています。この中にある「Product」と「ProductCategory」という2つのテーブルにあるデータ内で、「Color」が「"Black"」に該当するデータを抽出するクエリを実行し、結果セットをC1FlexGridコントロールで表示します。
まず、ソリューションエクスプローラのプロジェクト名の上でマウスの右ボタンを押して、ショートカットメニューから[追加]-[新しい項目]を選びます。
テンプレートリストから[ADO.NET Entity Data Model]を選び、[追加]ボタンをクリックします。
[データベースから生成]が選択されているのを確認し、[次へ]ボタンをクリックします。
[新しい接続]ボタンをクリックし、[Microsoft SQL Server データベースファイル]を選択して[続行]ボタンを押します。
[参照]ボタンをクリックして、使用するデータベースファイルを選びます。
[テスト接続]ボタンをクリックし、データベースファイルに接続できることを確認します。
ウィザードに戻り、[エンティティ接続設定に名前を付けてApp.Configに保存]欄の名前を「sql_db1」に変更し、[次へ]ボタンをクリックします。プロジェクトにコピーするかどうかのダイアログが表示されたら、そのままOKボタンをクリックします。
データベースオブジェクトを指定する画面に移るので、[テーブル]を展開し[Product]と[ProductCategory]の2つのテーブルにチェックを付け[完了]ボタンをクリックします。
データベースが組み込まれると、プロジェクトに「Model1.edmx」というファイルが追加され、2つのテーブルデータがリレーション付きで表示されます。
これで、プロジェクトにデータベースファイルを組み込むことができました。
データをセットする処理の作成
データベースファイルを組み込んだら、続いてこのデータベースデータをC1FlexGridコントロールに連結するコードを作成していきます。
データの抽出とビューの作成
データの抽出手順は、最初に必要なデータを抽出するクエリを実行します。そして、この結果セットをC1FlexGridコントロールの「ListCollectionView」オブジェクトにしてItemSourceプロパティに組み込めば、抽出したデータをコントロール上で表示できます。
まず、ADOデータエンティティのインスタンスを作成します。次に、ObjectQueryオブジェクトを作成し、クエリのSQL文を作成します。
そして、「ListCollectionView」オブジェクトのインスタンスを作成します。引数は、クエリの結果セットをIListオブジェクトにしたものです。このListCollectionViewオブジェクトをC1FlexGridコントロールのItemSourceプロパティにセットします。
Imports System.Data.Objects Imports C1.WPF.FlexGrid Class MainWindow Dim dataEntities As sql_db1 = New sql_db1 Private view As ListCollectionView Private Sub Window_Loaded(sender As System.Object, e As System.Windows.RoutedEventArgs) Handles MyBase.Loaded Dim products As ObjectQuery(Of Product) = dataEntities.Product Dim query = _ From product In products _ Where product.Color = "Black" _ Order By product.ListPrice _ Select product.Name, product.Color, CategoryName = product.ProductCategory.Name, product.ListPrice 'Viewの作成 view = New ListCollectionView(query.ToList) C1FlexGrid1.ItemsSource = view
using System.Data.Objects; using C1.WPF.FlexGrid; namespace WPF_FG_Data_cs { /// <summary> /// MainWindow.xaml の相互作用ロジック /// </summary> public partial class MainWindow : Window { sql_db1 dataEntities = new sql_db1(); ListCollectionView view; private void Window_Loaded(object sender, RoutedEventArgs e) { ObjectQuery<Product> products = dataEntities.Product; var query = from product in products where product.Color == "Black" orderby product.ListPrice select new { product.Name, product.Color, CategoryName = product.ProductCategory.Name, product.ListPrice }; view = new ListCollectionView(query.ToList()); C1FlexGrid1.ItemsSource = view;
列ヘッダの装飾
データがC1FlexGridコントロールに連結されると、自動的に列見出しとデータ数に見合う行列数のセルが作成されます。列見出しは、デザイン時は列見出しなどは決まっていないため、デザインするのであればビューを設定し終わってからになります。
ここでは、「ColumnHeaderBackground」「ColumnHeaderForeground」プロパティを使用して、列ヘッダの背景色と文字色を変更しています。これらのプロパティはコレクションオブジェクトに属しているので、一括ですべての列ヘッダを操作できます。
'列見出しの装飾 C1FlexGrid1.ColumnHeaderBackground = New SolidColorBrush(Colors.Purple) C1FlexGrid1.ColumnHeaderForeground = New SolidColorBrush(Colors.White) End Sub
C1FlexGrid1.ColumnHeaderBackground = new SolidColorBrush(Colors.Purple); C1FlexGrid1.ColumnHeaderForeground = new SolidColorBrush(Colors.White); }
グループ化の処理
前ページで解説したとおり、データのソートは列ヘッダに組み込まれている機能を自動的に使用できるようになるため、ここではデータのグループ化を行う処理を、チェックボックスのイベントハンドラに組み込みます。
グループ化の実行は、「GroupDescriptions」コレクションオブジェクトへ、Addメソッドを使用してグループ化したいデータを「PropertyGroupDescription」オブジェクトにして設定します。また、グループ化を解除したい場合は、「GroupDescriptions」クラスのClearメソッドを実行するだけです。
Private Sub CheckBox1_Checked(sender As System.Object, e As System.Windows.RoutedEventArgs) view.GroupDescriptions.Add(New PropertyGroupDescription("CategoryName")) End Sub Private Sub CheckBox1_Unchecked(sender As System.Object, e As System.Windows.RoutedEventArgs) view.GroupDescriptions.Clear() End Sub
private void CheckBox1_Checked(object sender, RoutedEventArgs e) { view.GroupDescriptions.Add(new PropertyGroupDescription("CategoryName")); } private void CheckBox1_Unchecked(object sender, RoutedEventArgs e) { view.GroupDescriptions.Clear(); }
まとめ
今回は、SQL Serverのデータから必要なデータを抽出して、C1FlexGridコントロールに連結モードで接続して表示しました。データベースの設定は、WPF標準のDataGridコントロールと同じ方法が使用でき、データベースをプロジェクトに組み込むだけで簡単にデータを表形式で表示できます。
連結モードでは、データのソート、グループ化、集計などが簡単に行えるため、C1FlexGridは、データベースのフロントエンドアプリケーション作成にはもってこいのコントロールだと思います。