演習: 動的リソースを使用して要素を更新する
この演習では、DynamicResource マークアップ拡張機能を使用して、リソースの値が変化したときに TipCalculator UI を更新します。
この演習は前の演習の続きです。 以下の手順の開始点として既存のソリューションを使用するか、前の演習でクローンしたリポジトリ内の exercise2/TipCalculator フォルダーにある、TipCalculator プロジェクトを開きます。
コードの繰り返しの検索
このアプリでは、StandardTipPage ページのために、単純な"淡色" と "濃色" の配色を実装しています。 ここで、色の変更に使用するコードを調べます。
StandardTipPage.xaml.cs ファイルを開きます。
UI の色を更新する 2 つのイベント ハンドラーを検索します。
private Color colorNavy = Colors.Navy; private Color colorSilver = Colors.Silver; ... void OnLight(object sender, EventArgs e) { LayoutRoot.BackgroundColor = colorSilver; tipLabel.TextColor = colorNavy; billLabel.TextColor = colorNavy; totalLabel.TextColor = colorNavy; tipOutput.TextColor = colorNavy; totalOutput.TextColor = colorNavy; } void OnDark(object sender, EventArgs e) { LayoutRoot.BackgroundColor = colorNavy; tipLabel.TextColor = colorSilver; billLabel.TextColor = colorSilver; totalLabel.TextColor = colorSilver; tipOutput.TextColor = colorSilver; totalOutput.TextColor = colorSilver; } ...
コードでは、各コントロールの色を個々に更新しているので、コードが繰り返されることがわかります。
コードからのリソースの更新
ページのリソース ディクショナリに格納されているいくつかのリソースを更新するコードを記述することから開始します。
OnLight メソッドからすべてのコードを削除します。
OnLight メソッドに、次に表示されているコードを追加してください。 このコードでは、ページのリソース ディクショナリ内の fgColor リソースを colorNavy 変数の値に設定し、bgColor リソースを colorSilver 変数の値に設定します。 colorNavy 変数と colorSilver 変数では、静的メソッド Color.FromRgb を使用しているので、16 進数の値を色に変換することが容易になっています。
void OnLight(object sender, EventArgs e) { Resources["fgColor"] = colorNavy; Resources["bgColor"] = colorSilver; }
OnDark メソッドに対して前の 2 つの手順を繰り返しますが、色は反転させます。fgColor を colorSilver に設定し、bgColor を colorNavy に設定します。
void OnDark(object sender, EventArgs e) { Resources["fgColor"] = colorSilver; Resources["bgColor"] = colorNavy; }
アプリを実行します。 [濃色] ボタンと [淡色] ボタンを選択します。 UI が変更されることはありません。 コードによってディクショナリ内のリソースの値が変更されても、新しい値は UI に伝達されません。 問題は、StaticResource マークアップ拡張機能を使用して XAML コード内の値を設定していることです。
UI の動的な更新
問題を修正するため、更新されたリソースの値が UI に読み込まれるように XAML を変更します。
アプリを停止し、StandardTipPage.xaml ファイルを開きます。
リソースの値から色を割り当てる場所をすべて検索します。 例に示すように、StaticResource マークアップ拡張機能の使用を DynamicResource の使用に置き換えてください。
<Grid x:Name ="LayoutRoot" BackgroundColor="{DynamicResource bgColor}" Padding="10"> ... <Label x:Name="billLabel" Text="Bill" TextColor="{DynamicResource fgColor}" ... /> <Label x:Name="tipLabel" Text="Tip" TextColor="{DynamicResource fgColor}" ... /> <Label x:Name="totalLabel" Text="Total" TextColor="{DynamicResource fgColor}" ... /> ...
Note
FontSize プロパティを StaticResource から DynamicResource に変更しないでください。
アプリを実行します。 [濃色] ボタンと [淡色] ボタンを選択します。 これで UI が正しく更新されるようになりました。