SiverlightのDataGridハローワールドをやってみます。
System.Windows.Controls.Data.dllを追加する。
VisualStudioでSilverlightアプリケーションを作成した場合、初期状態ではデータグリッドを含むアセンブリが参照されていません。そのため、最初に「参照の追加」を行います。
MSDNを調べてみますと、DataGridはSystem.Windows.Controls.Data.dllに含まれていることがわかります。
DataGrid クラス (System.Windows.Controls)
後は、[プロジェクト] メニューの [参照の追加] をクリックします。そして、[参照の追加] ダイアログ ボックスの [.NET] タブで、[System.Windows.Controls.Data] を選択すれば作業完了です。
DataGrid用のxmlns属性を追加する。
UserControlタグ内に追加する。
<!--MainPage.xaml-->
xmlns:sdk="http://schemas.microsoft.com/winfx/2006/xaml/presentation/sdk"
データグリッドをXAMLに定義する。
ここまで準備ができたならば、XAMLにDataGridを追加することができます。
<sdk:DataGrid x:Name="DgrBmiRecords" Height="150" Margin="5,0,5,5" IsReadOnly="True"/>
「sdk」は、上で指定したXMLネームスペース名となります。
今回は、DataGrid上でデータの編集する必要がないので、IsReadOnlyをtrueにしました。
以上でデータグリッドの設置は完了しました。
これ以降の作業は、データグリッドへデータを追加したり削除したりする機能を実装します。
データグリッドにセットするデータクラスを定義する。
ItemsSourceプロパティにリスト型のインスタンスを設定すると、データグリッドにデータが表示されます。このリスト型にセットするデータクラスを定義します。
今回はこんな感じにして見ました。
public class BMIRecord { /// <summary>BMIを記録した日付</summary> public DateTime Date { get; set; } /// <summary>BMI</summary> public double BMI { get; set; } /// <summary>標準値22とBMIとの差分</summary> public double HyojunSa { get; set; } /// <summary>身長</summary> public double Height { get; set; } /// <summary>体重</summary> public double Weight { get; set; } }
データグリッドのItemsSourceを初期化する。
データグッドのItemsSourceにインスタンスをセットします。ItemsSourceプロパティはIEnumerable型なのでアクセスするたびにキャストするのは手間がかかるので、MainPageのフィールドに保持しておきます。
private ObservableCollection<BMIRecord> itemsSource = new ObservableCollection<BMIRecord>();
このフィールドをMainPageのコンストラクタでデータグリッドにセットします。
public MainPage() { InitializeComponent(); // データグリッドの初期化 DgrBmiRecords.ItemsSource = this.itemsSource; this.RegistorEventHandler(); }
ObservableCollectionは、項目が追加、削除されたときなどにデータグリッドに通知を行ってくれるコレクションクラスです。例えば、ObservableCollectionにBMIRecordインスタンスを追加すると、データグリッドにもそのデータが表示されます。
データグリッドに行を追加する。
データグリッドにBMIRecordインスタンスを追加するロジックを記述します。タイミングは、計算ボタンが押されたときとします。
private void AddBmiRecordToDataGrid(double bmi, double height, double weight) { BMIRecord record = new BMIRecord(); record.Date = DateTime.Today; record.BMI = bmi; record.HyojunSa = bmi - 22D; record.Height = height; record.Weight = weight; this.itemsSource.Add(record); }
データグリッドの行を削除する。
画面に削除ボタンを追加し、この削除ボタンがクリックされたときに、データグリッドで選択されている行を削除するロジックを記述します。
private void BtnSakujo_Click(object sender, RoutedEventArgs e) { int selectedIndex = DgrBmiRecords.SelectedIndex; if (selectedIndex >= 0) { // SelectedIndexが0以上ならば、DataGridで行が選択されているということなので、 // その選択行のアイテムを消す。 this.itemsSource.RemoveAt(selectedIndex); } }
全ソースコード
以上で、データグリッドの実装は完了です。XAMLとcsコードの全容を書いておきます。
<UserControl x:Class="BMICalculator.MainPage" xmlns:contorlData="clr-namespace:System.Windows.Controls;assembly=System.Windows.Controls.Data" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" mc:Ignorable="d" d:DesignHeight="300" d:DesignWidth="400"> <StackPanel x:Name="LayoutRoot"> <StackPanel Orientation="Horizontal" Margin="5"> <TextBlock Text="体重" Width="80" VerticalAlignment="Center" Margin="5,0"/> <TextBox x:Name="TbxWeight" Width="150"/> <TextBlock Text="Kg" VerticalAlignment="Center" Margin="5,0"/> </StackPanel> <StackPanel Orientation="Horizontal" Margin="5"> <TextBlock Text="身長" Width="80" VerticalAlignment="Center" Margin="5,0"/> <TextBox x:Name="TbxHeight" Width="150"/> <TextBlock Text="cm" VerticalAlignment="Center" Margin="5,0"/> </StackPanel> <TextBlock x:Name="TblValidateResult" Text="" Margin="5" Foreground="Red" Height="18"/> <Button x:Name="BtnCalc" Content="計算" Width="80" HorizontalAlignment="Left" Margin="20,0"/> <StackPanel Orientation="Horizontal" Margin="5"> <TextBlock Text="あなたのBMI" Width="80" VerticalAlignment="Center" Margin="5,0"/> <TextBox x:Name="TbxBMI" Width="150" IsReadOnly="True"/> </StackPanel> <Button x:Name="BtnSakujo" Content="削除" HorizontalAlignment="Right" Margin="5"/> <contorlData:DataGrid x:Name="DgrBmiRecords" Height="150" Margin="5,0,5,5" IsReadOnly="True"/> </StackPanel> </UserControl>
public partial class MainPage : UserControl { private ObservableCollection<BMIRecord> itemsSource = new ObservableCollection<BMIRecord>(); public MainPage() { InitializeComponent(); // データグリッドの初期化 DgrBmiRecords.ItemsSource = this.itemsSource; this.RegistorEventHandler(); } private void RegistorEventHandler() { BtnCalc.Click += new RoutedEventHandler(this.BtnCalc_Click); BtnSakujo.Click += new RoutedEventHandler(this.BtnSakujo_Click); } private void BtnCalc_Click(object sender, RoutedEventArgs e) { // エラー結果表示テキストブロックを初期化 TblValidateResult.Text = string.Empty; // 体重kg double weight; if (!double.TryParse(TbxWeight.Text, out weight) || weight <= 0) { TblValidateResult.Text = "体重は正の数字を入力してください"; return; } // 身長m double height; if (!double.TryParse(TbxHeight.Text, out height) || height <= 0) { TblValidateResult.Text = "身長は正の数字を入力してください"; return; } // BMI=体重(kg)/身長(m)の二乗 double bmi = weight / Math.Pow(height / 100D, 2); // bmiをコントロールにセットする。 TbxBMI.Text = bmi.ToString(); // データグリッドにBMI結果を追加する。 this.AddBmiRecordToDataGrid(bmi, height, weight); } private void AddBmiRecordToDataGrid(double bmi, double height, double weight) { BMIRecord record = new BMIRecord(); record.Date = DateTime.Today; record.BMI = bmi; record.HyojunSa = bmi - 22D; record.Height = height; record.Weight = weight; this.itemsSource.Add(record); } private void BtnSakujo_Click(object sender, RoutedEventArgs e) { int selectedIndex = DgrBmiRecords.SelectedIndex; if (selectedIndex >= 0) { // SelectedIndexが0以上ならば、DataGridで行が選択されているということなので、 // その選択行のアイテムを消す。 this.itemsSource.RemoveAt(selectedIndex); } } }
まとめ
DataGridのハローワールドを実装しました。今回は、列ヘッダーがアイテムクラス(BMIRecordクラス)のプロパティと一致する例を示しました。列を制御する例は次回以降に行う予定です。