バインディングモード
データバインドでは、ターゲットとなるコントロールとデータソースを結びつけますが、双方のデータを通知するか否かをコントロールしているプロパティがBindingオブジェクトのモードプロパティです。
このプロパティは下記のように3種類の選択肢が存在しています。
- OneTime
- OneWay
- TwoWay
データソースによってターゲット(コントロール)が初期化されます。ただし、それ以降の変更は反映されません。
データソースの値が変更されると、ターゲット(コントロール)も自動的に更新されます。ただし、ターゲットの変更はソースプロパティに反映されません。
データソースまたはターゲット(コントロール)のどちらか一方が変更されると、もう一方も自動的に更新されます。
例えば、コントロールに表示するデータ自体が、静的な表記であればOneTime、参照専用であればOneWay、ユーザーからの入力を伴う場合はTwoWayと使い分けることで、システム全体のパフォーマンスを向上することが可能です。

ただし、OneWayバインディングとTwoWayバインディングでは、データソースの変更を検出するために、データソース側にINotifyPropertyChangedインターフェース(プロパティの変更通知機構)を実装する必要があります。これを実装するには、前回の記事のようにADO.NET Data Servicesのサービスから取得したデータをそのままコントロールに送るのではなく、クライアント側にエンティティクラスを作り(INotifyPropertyChangedインターフェースを継承した実装にします)、そのクラスを経由してコントロールとバインドをかける形にします。この実装を前述したサンプルの中で見てみましょう。
商品を一覧から選択した後の画面(商品詳細画面)を例にとります。
まず、商品詳細画面(Product.xaml)のコードです。
<TextBlock Text="商品詳細" FontSize="18" />
<TextBlock x:Name="productNameTextBlock"
Text="{Binding Product.Name}"
FontSize="16" FontWeight="Bold" />
<Image x:Name="productDetailImage"
Source="{Binding ProductImageUrl,
Converter={StaticResource UriToBitmapImageConverter}}"/>
<ListBox x:Name="colorListBox"
ItemsPanel="{StaticResource HorizonalWrapPanel}"
ScrollViewer.HorizontalScrollBarVisibility="Disabled"
SelectionChanged="colorListBox_SelectionChanged"
ItemsSource="{Binding ProductColors}"
SelectedItem="{Binding ProductColor, Mode=TwoWay}"
VerticalAlignment="Center"
HorizontalAlignment="Center"
Margin="0">
<ListBox.ItemTemplate>
<DataTemplate>
<Border BorderBrush="Gray" BorderThickness="1" Margin="2,0">
<Image Source="{Binding ProductThumbnailUrl,
Converter={StaticResource UriToBitmapImageConverter}}"
Margin="2" Width="40" />
</Border>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
注目すべきは、各コントロールのバインド先です。
例えばTextBlock(productNameTextBlock)のTextプロパティはProduct.Nameとバインドしています。モードは省略していますが、この場合OneWayになります。
また、ListBox(colorLostBox)はItemsSourceプロパティはProductColorsとなっているので、ProductColorsはコレクションのような集合型の値であることが推測できます。更に、SelectedItemプロパティは、エンティティクラスのProductColorに対してTwoWayバインドを行っているのが分かります。
つまり、ListBoxの値は、ProductColorsがデータの元ネタとなっていて、リストを選択するとエンティティオブジェクトのProductColorに選択値を通知することになります。
