このトピックはまだ評価されていません - このトピックを評価する

クイックスタート:Windows Phone のコントロールへのデータ バインディング

2013/12/05

対象: Windows Phone 8 | Windows Phone OS 7.1

ほとんどの Windows Phone アプリはコントロール内にデータを表示します。多くの場合、データはビジネス オブジェクトか、株価情報、見出し、画像などのビジネス オブジェクトの集まりです。また、ユーザーがリストから項目を選択すると、その項目に関する詳細がテキスト ボックスなどの別のコントロール内に表示されるようにしたいことがよくあります。

このクイックスタートでは、コントロールを 1 つの項目にバインドする方法およびリスト コントロールを項目のコレクションにバインドする方法について説明します。さらに、このクイックスタートでは、コントロール項目の表示のカスタマイズ、選択に基づく詳細ビューの実装、および表示用のデータの変換を行う方法についても説明します。

このトピックは、次のセクションで構成されています。

データ バインディングはターゲットとソースで構成されます。バインディングのターゲットは一般的にコントロールのプロパティです。ターゲットは DependencyProperty である必要があります。

コントロールの 1 つの項目へのバインディングを次の例に示します。ターゲットは TextBox コントロールの Text プロパティです。ソースは単純な音楽の Recording クラスです。


<Grid x:Name="ContentPanel" Grid.Row="1" Margin="12,0,12,0">
    <TextBox VerticalAlignment="Top" IsReadOnly="True" Margin="5"
       TextWrapping="Wrap" Height="120" Width="400"
       Text="{Binding}" x:Name="textBox1" />
</Grid>


// Constructor
public MainPage()
{
   InitializeComponent();
   // Set the data context to a new Recording.
   textBox1.DataContext = new Recording("Chris Sells", "Chris Sells Live",
      new DateTime(2008, 2, 5));
}

// A simple business object
public class Recording
{
   public Recording() { }
   public Recording(string artistName, string cdName, DateTime release)
   {
      Artist = artistName;
      Name = cdName;
      ReleaseDate = release;
   }
   public string Artist { get; set; }
   public string Name { get; set; }
   public DateTime ReleaseDate { get; set; }
   // Override the ToString method.
   public override string ToString()
   {
      return Name + " by " + Artist + ", Released: " + ReleaseDate.ToShortDateString();
   }
}

アプリを実行すると、アプリは次のような外観になります。

Binding To Controls

音楽の録音を TextBox に表示するには、マークアップ拡張機能を使用してコントロールの Text プロパティを Binding に設定します。この例では、バインディング モードは既定で OneWay です。これはデータはソースから取得されますが、変更はソースに反映されないことを示します。

Recording クラスには、3 つのパブリック プロパティと ToString メソッドのオーバーライドがあります。それらのプロパティは、ArtistName、および ReleaseDate です。書式設定が指定されていない場合は、表示を目的としてバインドされたオブジェクトについて ToString メソッドが呼び出されるので、ToString メソッドは重要です。バインディングの Source プロパティは直接設定されません。代わりに、TextBox コントロールの DataContext プロパティが新しい Recording オブジェクトに設定されます。

前の例では、コントロールにデータをバインドするために使用する構文を示しましたが、これはあまり現実的はありません。より一般的なシナリオでは、ビジネス オブジェクトのコレクションにバインドします。汎用の ObservableCollection<T> クラスは、INotifyPropertyChanged および INotifyCollectionChanged インターフェイスを実装するので、データ バインディングに使用するコレクションとして有効な選択肢です。これらのインターフェイスは、リスト内の項目が変更されたり、リスト自体のプロパティが変更されたりしたときのバインドされたコントロールへの変更通知を提供します。コレクション内のオブジェクトのプロパティの変更を反映してバインドされたコントロールを更新したい場合は、ビジネス オブジェクトも INotifyPropertyChanged を実装する必要があります。

音楽の Recording オブジェクトのコレクションを ListBox にバインドする例を次に示します。


<Grid x:Name="ContentPanel" Grid.Row="1" Margin="12,0,12,0">
   <ListBox x:Name="ListBox1" ItemsSource="{Binding}"
      Height="200" Width="400"/>
</Grid>

public ObservableCollection<Recording> MyMusic = new ObservableCollection<Recording>();

public MainPage()
{
   InitializeComponent();
   // Add items to the collection.
   MyMusic.Add(new Recording("Chris Sells", "Chris Sells Live",
   new DateTime(2008, 2, 5)));
   MyMusic.Add(new Recording("Luka Abrus",
      "The Road to Redmond", new DateTime(2007, 4, 3)));
   MyMusic.Add(new Recording("Jim Hance",
      "The Best of Jim Hance", new DateTime(2007, 2, 6)));
   // Set the data context for the list box.
   ListBox1.DataContext = MyMusic;
}

Binding to controls collection

音楽の録音を ListBox に表示するには、コントロールの ItemsSource プロパティを Binding に設定し、ListBox コントロールの DataContext プロパティをバインディングのソースを提供する Recording オブジェクトのコレクションに設定します。コレクション内の項目ごとに ListBoxItem が作成されます。ToString が各 Recording オブジェクトで自動的に呼び出され、リスト ボックス項目に表示されます。

項目の ToString メソッドを使用してリスト内に項目を表示することができます。ただし、データ バインドされた項目の表示をカスタマイズできるようにするシナリオの方が一般的です。その場合は、DataTemplate を使用することでコントロール内にリスト項目を表示する方法をカスタマイズできます。一般的に、コンテンツ コントロールの ContentTemplate プロパティまたは項目コントロールの ItemTemplate プロパティを使用してデータ テンプレートを設定します。

データ テンプレートを使用してリスト ボックスにバインドされた同じ録音の一覧の例を次に示します。リスト ボックスは ItemsControl であり、これは、各項目の ItemTemplate プロパティをデータ テンプレートに設定することによって各項目のデータ テンプレートを確立することを意味します。


<ListBox x:Name="ListBox1" Margin="5"
   Width="450" Height="200" HorizontalAlignment="Left"
   ItemsSource="{Binding}" >
   <ListBox.ItemTemplate>
      <DataTemplate>
         <StackPanel Orientation="Horizontal" Margin="2">
            <TextBlock Text="Artist:" Margin="2" />
            <TextBlock Text="{Binding Artist}" Margin="2" />
            <TextBlock Text="CD:" Margin="10,2,0,2" />
            <TextBlock Text="{Binding Name}" Margin="2" />
         </StackPanel>
      </DataTemplate>
   </ListBox.ItemTemplate>
</ListBox>
Binding to control data template

XAML で、データ テンプレートの定義を表示することができます。このデータ テンプレートは StackPanel と 4 つの TextBlock コントロールを含んでいます。スタック パネルは、水平方向にして 4 つのテキスト ボックス コントロールを並べて表示することができます。2 つの TextBlock コントロールは、Recording オブジェクトの Artist および Name プロパティにバインドされます。他の 2 つの TextBlock コントロールは静的テキストを表示します。各バインドされる項目に関して、バインディングは Recording オブジェクトのプロパティへのパスを提供します。前の例のように、このバインディングはデータ コンテキストが録音のリストに設定されていることに依存します。

コレクションから項目が選択されたときに項目の詳細を表示するには、適切な UI を作成し、その UI を表示するデータにバインドする必要があります。さらに、CollectionViewSource をデータ コンテキストとして使用し、詳細ビューを現在の項目にバインドできるようにする必要があります。

次の例は、同じ録音のリストを示していますが、今回のリストは CollectionViewSource インスタンスのデータ ソースです。レイアウト ルートのデータ コンテキストは、コレクションのビュー ソースに設定され、リスト ボックスと詳細ビューは、レイアウト ルートからデータ コンテキストを継承します。これにより、リスト ボックスに同じ項目の一覧を表示しながら、詳細ビューに現在の項目に関する情報を表示することができます。


<!--The UI for the details view-->
<StackPanel x:Name="RecordingDetails">
   <TextBlock FontWeight="Bold" Text="{Binding Artist}" Margin="5,0,0,0"/>
   <TextBlock FontStyle="Italic" Text="{Binding Name}" Margin="5,0,0,0"/>
   <TextBlock Text="{Binding ReleaseDate}" Margin="5,0,0,0" />
</StackPanel>

//ListBox1.DataContext = MyMusic;
LayoutRoot.DataContext = new CollectionViewSource { Source = MyMusic };
Binding to control details

この例では、録音の詳細を表示する 3 つのテキスト ブロックを含む StackPanel が追加されています。各テキスト ブロックの Text プロパティは Recording オブジェクト上のプロパティにバインドされます。

TextBox などの非文字列型を書式設定してコントロール内に表示する場合は、コンバーターを使用することができます。たとえば、日付だけを表示する代わりにラベルと書式設定した日付を表示することができます (日付だけを書式設定したい場合は StringFormat プロパティを使用できます)。録音のリスト内にリリース日のコンバーターを実装する例を次に示します。


<phone:PhoneApplicationPage
   x:Class="PhoneApp1.MainPage"


      ...
   xmlns:local="clr-namespace:PhoneApp1"
      ...
   >

<phone:PhoneApplicationPage.Resources>
   <local:StringFormatter x:Key="StringConverter"/>
</phone:PhoneApplicationPage.Resources>

   ...

   <!--ContentPanel - place content here-->
   <StackPanel x:Name="ContentPanel" Grid.Row="1" Margin="12,0,12,0">
      <ListBox x:Name="ListBox1" Margin="5"
         Width="450" Height="200" HorizontalAlignment="Left"
         ItemsSource="{Binding}" >
         <ListBox.ItemTemplate>
            <DataTemplate>
               <StackPanel Orientation="Horizontal" Margin="2">
                  <TextBlock Text="Artist:" Margin="2" />
                  <TextBlock Text="{Binding Artist}" Margin="2" />
                  <TextBlock Text="CD:" Margin="10,2,0,2" />
                  <TextBlock Text="{Binding Name}" Margin="2" />
               </StackPanel>
            </DataTemplate>
         </ListBox.ItemTemplate>
      </ListBox>
      <!--The UI for the details view-->
      <StackPanel x:Name="RecordingDetails">
         <TextBlock Text="{Binding Artist}" />
         <TextBlock Text="{Binding Name}" />
         <TextBlock Text="{Binding ReleaseDate,
            Converter={StaticResource StringConverter},
            ConverterParameter=Released: \{0:D\}}" />
      </StackPanel>
   </StackPanel>


public class StringFormatter : IValueConverter
{
   // This converts the value object to the string to display.
   // This will work with most simple types.
   public object Convert(object value, Type targetType,
   object parameter, System.Globalization.CultureInfo culture)
   {
      // Retrieve the format string and use it to format the value.
      string formatString = parameter as string;
      if (!string.IsNullOrEmpty(formatString))
      {
         return string.Format(culture, formatString, value);
      }
      // If the format string is null or empty, simply
      // call ToString() on the value.
      return value.ToString();
   }

   // No need to implement converting back on a one-way binding
   public object ConvertBack(object value, Type targetType,
   object parameter, System.Globalization.CultureInfo culture)
   {
      throw new NotImplementedException();
   }
}

Binding to controls convert data

コンバーターは、ConvertConvertBack という 2 つのメソッドを持つ IValueConverter インターフェイスから派生するクラスです。データ ソースからバインディング ターゲットへの一方向のバインディングの場合、Convert メソッドのみを実装する必要があります。この例のコンバーターはかなり汎用的です。目的の文字列形式をパラメーターとして渡すことができ、コンバーターは Format メソッドを使用して変換を実行します。形式文字列が渡されない場合、コンバーターはそのオブジェクトに対して ToString を呼び出した結果を返します。

コンバーターを実装したら、コンバーター クラスのインスタンスを作成し、このインスタンスを使用するようにバインディングを指定します。この例では、XAML でこれを実行します。コンバーターのインスタンスは、静的リソースとして作成され、キーが割り当てられます。キーは、コンバーターのプロパティがバインドで設定されるときに使用されます。この例のコンバーターはかなり汎用的です。目的の文字列形式をパラメーターとして渡すことができ、コンバーターは Format メソッドを使用して変換を実行します。形式文字列が渡されない場合、コンバーターはそのオブジェクトに対して ToString を呼び出した結果を返します。

この情報は役に立ちましたか。
(残り 1500 文字)
フィードバックをいただき、ありがとうございました
表示:
© 2014 Microsoft. All rights reserved.