INotifyCollectionChanged
先日のINotifyPropertyChangedに続いて、INotifyCollectionChangedを紹介します。Silverligth 2ではコントロールなどの要素のプロパティの変更やコレクションの追加削除を通知する機能は要素に実装されていないので、自分で実装する必要があります。そのためのインターフェイスがINotifyPropertyChangedとINotifyCollectionChangedです。
例えば、TextBoxで入力したデータをDataGridで表示したい様な場合にINotifyCollectionChangedを利用します。まず次のようにXAMLで入力とDataGridを宣言します。
<UserControl x:Class="MyDataGrid.Page"
xmlns="https://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="https://schemas.microsoft.com/winfx/2006/xaml"
xmlns:data="clr-namespace:System.Windows.Controls;
assembly=System.Windows.Controls.Data"
Width="600" Height="300" Loaded="UserControl_Loaded">
<Grid x:Name="LayoutRoot" Background="White">
<Grid.RowDefinitions>
<RowDefinition Height="50" />
<RowDefinition Height="*" />
</Grid.RowDefinitions>
<StackPanel Orientation="Horizontal" Grid.Row="0" >
<TextBlock Text="Title" Margin="10" />
<TextBox x:Name="myTitle" Width="80" Margin="10"/>
<TextBlock Text="Author" Margin="10"/>
<TextBox x:Name="myAuthor" Width="80" Margin="10"/>
<TextBlock Text="ISBN" Margin="10"/>
<TextBox x:Name="myISBN" Width="80" Margin="10"/>
<Button Width="50" Height="30" Margin="10"
Content="Add" Click="Button_Click" />
</StackPanel>
<data:DataGrid x:Name="myDataGrid" Margin="20"
Grid.Row="1" Width="560" />
</Grid>
</UserControl>
コードビハインド全体はPage.xaml.csを添付しますので参照してください。ロード時にBooksCollectionのオブジェクトをmyDataGridのItemSoureceに代入します。DataGridのAutoGenerateColumnsはデフォルトtrueなので、自動的に列が生成されます。
private BooksCollection myBooks = new BooksCollection();
private void UserControl_Loaded(object sender, RoutedEventArgs e)
{
myDataGrid.ItemsSource = myBooks;
myBooks.Add(new Book("XAMLプログラミング",
"川西 裕幸",
"9784797339161"));
}
BooksCollectionは次のようなINotifyColelctionChangedとCollectionの両方を継承するクラスとして作成しました。NotifyCollectionChangedEventHandlerを呼び出して、他の要素にコレクションが変更されたことを伝えます。関連する要素(ここではDataGrid)はそのイベントに応じて自動的に自分自身を更新します。
public class BooksCollection : Collection<Book>,
INotifyCollectionChanged
{
public new void Add(Book b)
{
base.Add(b);
OnCollectionChanged(NotifyCollectionChangedAction.Add,
b, this.IndexOf(b));
}
#region INotifyCollectionChanged Member
public event NotifyCollectionChangedEventHandler
CollectionChanged;
protected void OnCollectionChanged
(NotifyCollectionChangedAction action,
Book b, int index)
{
NotifyCollectionChangedEventHandler
handler = CollectionChanged;
if (handler != null)
handler(this,
new NotifyCollectionChangedEventArgs(action,
b, index));
}
#endregion
}
注意:DataGridを使うときは、参照設定にSystem.Windows.Controls.Dataを追加することを忘れないでください。