このパートでは、次のことを学習します。
- 必要に応じて表示されるようにデータを変換する方法。
- データを整理してデータクラスを作成する方法。
- 変更が行われたときに更新されるデータクラスを作成する方法。
- 変更が行われたときに更新されるデータのコレクションを作成する方法。
値変換
前の部分の例が、コンバーター設定を含むバインディングを示していることに気づいたかもしれません。 このパラメーターにより、コントロールはバインドされたプロパティの値を他の形式で表示できます。 これらの特定の例では、ConverterParameter設定で指定された文字列形式を使用して値が表示されます。 次のXAMLコードは、Date TextBlockのConverterおよびConverterParameterを示しています。
< TextBlock Style ="{StaticResource SummaryStyle}" Text ="{Binding Date, Converter={StaticResource StringFormatter}, ConverterParameter=\{0:d\} }" Width ="105" TextWrapping ="Wrap" /> * This source code was highlighted with Source Code Highlighter .
< TextBlock Style ="{StaticResource SummaryStyle}" Text ="{Binding Date, Converter={StaticResource StringFormatter}, ConverterParameter=\{0:d\} }" Width ="105" TextWrapping ="Wrap" /> * This source code was highlighted with Source Code Highlighter .
< TextBlock Style ="{StaticResource SummaryStyle}" Text ="{Binding Date, Converter={StaticResource StringFormatter}, ConverterParameter=\{0:d\} }" Width ="105" TextWrapping ="Wrap" /> * This source code was highlighted with Source Code Highlighter .
< TextBlock Style ="{StaticResource SummaryStyle}" Text ="{Binding Date, Converter={StaticResource StringFormatter}, ConverterParameter=\{0:d\} }" Width ="105" TextWrapping ="Wrap" /> * This source code was highlighted with Source Code Highlighter .
< TextBlock Style ="{StaticResource SummaryStyle}" Text ="{Binding Date, Converter={StaticResource StringFormatter}, ConverterParameter=\{0:d\} }" Width ="105" TextWrapping ="Wrap" /> * This source code was highlighted with Source Code Highlighter .
一般に、値コンバーターを使用すると、プロパティが互換性のない型であるか、値が目的の形式で格納されていない場合でも、コントロールを任意のプロパティにバインドできます。 データオブジェクトの追加のプロパティを実装して、他のプロパティを単純にラップし、バインドに必要な変換またはフォーマットを提供できます。 ただし、個々のビューにのみ必要なコードでデータモデルを乱雑にしないことをお勧めします。 値コンバーターを作成することにより、データモデルとそれを使用する表現の両方とは別に変換コードをカプセル化できます。
前の例では、Converterプロパティにはリソースとして定義されたオブジェクトの値があります。 次のXAMLコードは、 StringFormatterの新しいインスタンスを作成し、「StringFormatter」と呼ばれるStaticResourceとしてグリッドで使用できるように宣言します。
*このソースコードは、 ソースコードハイライターで強調表示されました。
- < Grid.Resources >
- < local:StringFormatter x:Key = "StringFormatter" />
- </ Grid.Resources >
値の変換を実行するには、 StringFormatterクラスでConvertおよびConvertBackメソッドを定義するIValueConverterインターフェイスを実装する必要があります。 バインディングはOneWayであるため、 StringFormatterクラスにはConvertメソッドのみが必要です。このメソッドは、次のコードに示すように、String.Formatメソッドを使用して文字列をフォーマットします。
*このソースコードは、 ソースコードハイライターで強調表示されました。
- パブリック クラス StringFormatter:IValueConverter
- {
- public object Convert ( object value 、Type targetType、 objectパラメーター、
- CultureInfoカルチャー)
- {
- //フォーマット文字列を取得し、それを使用して値をフォーマットします。
- var formatString = parameter as string ;
- if (! string .IsNullOrEmpty(formatString))
- {
- 文字列を返す.Format(culture、formatString、 value );
- }
- //フォーマット文字列がnullまたは空の場合、単にToString()を呼び出します
- //値について。
- 戻り 値 .ToString();
- }
- //一方向バインディングで逆変換を実装する必要はありません
- パブリック オブジェクト ConvertBack( オブジェクト 値 、タイプtargetType、
- オブジェクトパラメーター、CultureInfoカルチャ)
- {
- 新しい NotImplementedException()をスローします。
- }
- }
次の図は、StringFormatterコンバーターが使用されていない場合、したがって、使用されている場合の動作を示しています。
ZeroFormatter.csファイルの値を変換する別の例。 Fuel TrackerはZeroFormatterクラスを使用して、空の文字列としてnull値を表示します。 これは、ユーザーがデータ入力時に値を指定するオブジェクトにバインドするときに役立ちます。 たとえば、新しいオブジェクトの整数プロパティはデフォルトでゼロに設定されていますが、これらのプロパティを表示するコントロールは、ユーザーが値を入力する前に空になっている必要があります。
データクラスの作成
ユーザーインターフェイスにデータを表示する前に、通常、データをクラスに整理する必要があります。
データクラスはさまざまな方法で作成できます。 たとえば、外部データソースとやり取りするアプリケーションでは、ADO.NET Entity FrameworkまたはWCF Data Servicesを使用して生成されたデータクラスを使用できます。 単純なアプリケーションの場合、手動で作成されたプレーンオールドCLRオブジェクト(POCO-プレーンオールドCLRオブジェクト)のクラスを使用できます。 これらのクラスには、多くの場合、データと小さな変更通知コードを保存するためのプロパティが含まれています。
ヒント:
アプリケーションが自己完結型ではなく、さらに開発されることが予想される場合、より近代的なアーキテクチャの恩恵を受ける可能性があります。 これは通常、将来の変更の副作用を最小限に抑え、デバッグプロセスを容易にし、ユニットテストサポートを実装するために、別のクラスまたはレイヤーに追加のタイプのコードをカプセル化することを意味します。
XAMLアプリケーションでは、使用する共通テンプレートはModel-View-ViewModel(MVVM)です。 Fuel Trackerアプリケーションは比較的単純であるため、MVVMパターンを実装せず、この記事ではこのモデルについて詳しく説明しません。 このトピックの詳細については、次のリンクを参照してください。WindowsPhoneアプリケーションでのModel-View-ViewModelパターンの実装およびパターンと実践Windows Phone 7開発ガイド 。
Fuel Trackerはシンプルなアプリケーションであり、データモデルにCLRオブジェクトを使用します。 次の画像は、Fuel TrackerアプリケーションのCar 、 Fillup 、およびCarDataStoreクラスを示しています。 アプリケーションには他のクラスもありますが、これらは主なクラスです。
Carクラスには、ユーザーの車に関する情報が格納されます。 Fillupクラスには、各給油に関する情報が含まれています。 CarおよびFillupプロパティはすべて、補充のコレクションであるCar.FillupHistoryプロパティを除き、単純な値タイプです。 CarDataStoreクラスは、ページユーザーインターフェイスがバインドされているCarおよびFillupデータを保存およびロードするためのメソッドを含む一般的なクラスです。
Car クラスとFillupクラスはINotifyPropertyChangedインターフェイスを実装することに注意してください。 INotifyPropertyChangedは、ほとんどのデータバインディングタイプが常に最新のユーザーインターフェイスを表示するために必要です。 データバインディングの詳細については、前のセクション「データマッピング」を参照してください。
変更通知
アプリケーションは、次のようなさまざまな方法でデータクラスを使用します。値を直接表示し、ユーザーが値を変更できるようにする。 値を使用して他の値を計算したり、ユーザーインターフェイスの状態を変更したりします。 これらのすべての場合、プロパティ値が変更されたときにアプリケーションを更新する必要があります。 このため、クラスの変更通知クラスを実装すると非常に便利です。
変更の通知の可能性を提供するために、クラスはINotifyPropertyChangedインターフェイスを実装する必要があります。 変更の通知は必ずしも必要ではありませんが、非常に多くの一般的なシナリオで必要なので、万が一に備えてINotifyPropertyChangedを実装すると便利です。 Car.csの次のコード例に示すように、実装は簡単です。
*このソースコードは、 ソースコードハイライターで強調表示されました。
- パブリック クラス Car:INotifyPropertyChanged
- {
- プライベート ストリング _name;
- 公開 文字列名
- {
- get { return _name; }
- セット
- {
- _name = value ;
- NotifyPropertyChanged( "Name" );
- }
- }
- // ...その他のプロパティ...
- パブリック イベント PropertyChangedEventHandler PropertyChanged = delegate {};
- private void NotifyPropertyChanged( string propertyName)
- {
- PropertyChanged( this 、 新しい PropertyChangedEventArgs(propertyName));
- }
- }
オブジェクトをユーザーインターフェイスにバインドすると、バインドエンジンはPropertyChangedオブジェクトイベントをサブスクライブし、プロパティ値が変更されるたびにすべてのバインドされたコントロールを更新できるようにします。 PropertyChangedイベントは、 nullにならないように空のデリゲートによってトリガーされることに注意してください。 これにより、 NotifyPropertyChangedメソッドは、サブスクライバーがあるかどうかを最初に確認することなくイベントを発生させることができます。 このインターフェイスに慣れていない場合は、このテンプレートを繰り返して実装できます。
コレクションの変更通知
コレクションの追加や削除など、コレクションの変更通知を完全にサポートするには、コレクションでINotifyCollectionChangedインターフェイスを実装する必要があります。 ObservableCollectionは、フレームワークによって提供される動的なデータコレクションであり、ジェネリック型を含む場合があります。 ObservableCollectionはINotifyPropertyChangedとINotifyCollectionChangedの両方を実装しているため、コレクションの変更通知をサポートする最も簡単な方法は、単にアイテムをObservableCollectionに入れることです。 コレクション内のオブジェクトのプロパティ変更通知も受信する場合は、ObservableCollectionに配置した要素にINotifyPropertyChangedを実装する必要があります。
Fuel TrackerはFillupHistoryという1つのコレクションを使用します。これには、すべての給油に関する情報が含まれています。 FillupHistoryは、 Car.csの次のコード例に示すように、 FillupオブジェクトのObservableCollectionです。
*このソースコードは、 ソースコードハイライターで強調表示されました。
- public ObservableCollection <Fillup> FillupHistory
- {
- get { return _fillupHistory; }
- セット
- {
- _fillupHistory = value ;
- if (_fillupHistory!= null )
- {
- _fillupHistory.CollectionChanged + = デリゲート
- {
- NotifyPropertyChanged( "AverageFuelEfficiency" );
- };
- }
- NotifyPropertyChanged( "FillupHistory" );
- NotifyPropertyChanged( "AverageFuelEfficiency" );
- }
- }
このコードは、変更通知を使用して他のプロパティと対話する方法も示します。 満タン履歴または内部の要素を変更すると、平均燃費の計算に影響します。 したがって、 FillupHistoryプロパティを設定すると、それ自体とAverageFuelEfficiencyプロパティの変更通知が発生します。 さらに、新しいコレクションのCollectionChangedイベントハンドラーに関連付けられたプロパティを設定することにより、コレクション内のアイテムが追加、削除、または変更されるたびにAverageFuelEfficiencyの変更通知を受け取ります。
次の部分