Widowsストアアプリにおいて、アプリケーションの設定は設定チャームを通じて行います。実はFeedroでも設定チャームを通じたアプリケーションの設定画面の実装は行われています。試しにFeedroを起動し、Windows+[I](アルファベットのアイ)を押して設定チャームを開いてみてください。【一般】というFeedroが提供するメニュー項目が追加されています。この【一般】を選択すると【フィードを保持する日数】というコンボボックスがひとつ表示されているだけの設定画面が表示されます。
この設定項目により、RSSフィードから読み取ったブログ記事をローカルに保存する期間を選択できます。
この設定画面を実現するための、モデル、ビューモデルおよびビューについてそれぞれ見ていきましょう。
モデル
第6章で触れたようにアプリケーションの設定情報を保存するには、Windows.Storage.ApplicationDataクラスのオブジェクトのLocalSettingsプロパティを用います。このLocalSettingsプロパティは永続化機能をもつオブジェクト辞書で、名前 を付けてオブジェクトを保存、読み出しする機能を提供します。以下のような点が異なりますが、 System.Collections.Generics.Dictionaryクラスと似たようなものだと考えるとわかりやすいでしょう。
- 自動的にファイルに保存される
- キーは文字列に固定されている
- 値となるオブジェクトの型はWindows Runtimeがサポートする標準型に限定される
【注】Windows Runtimeがサポートする標準型の一覧についてはこちらを参考にしてください。
アプリケーションのコードからApplicationDataのLocalSettingsプロパティを直接操作しても実用上は問題ありませんが、ここではSettingsHelperというユーティリティクラスを定義しておきましょう。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 |
using Windows.Storage; namespace Feedro.Model.Helper { public static class SettingHelper { public static T GetLocalSetting(string name, T defaultValue) { object value = ApplicationData.Current.LocalSettings.Values[name]; return value != null ? (T)value : defaultValue; } public static void SetLocalSetting(string name, T value) { ApplicationData.Current.LocalSettings.Values[name] = value; } } } |
このようなユーティリティークラスを介して設定情報を取り扱うことで、のちのち、設定情報を端末間で同期させたい、といった要件がでてきた時に対応しやすくなります。さらにその上で、設定値そのものをモデルStoreクラスのプロパティDaysToKeepとしてアクセスできるようにしておきましょう。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 |
public class Store { .... private const string SettingsDaysToKeep = "DaysToKeep"; private const int DefaultSettingsDaysToKeep = 90; .... public int DaysToKeep { get { return SettingHelper.GetLocalSetting(SettingsDaysToKeep, DefaultSettingsDaysToKeep); } set { SettingHelper.SetLocalSetting(SettingsDaysToKeep, value); } } .... } |
ビューモデル
ビューモデルは以下のふたつのプロパティを実装しています。
DaysToKeepOptions | コンボボックスで表示する選択可能な日数の一覧一週間(7)、二週間(14)、一か月(30)、二か月(60)、三か月(90)、半年(180)、一年(365) |
SelectedDaysToKeep | コンボボックスで選択された日数 |
SelectedDaysToKeepの実装は、Store.DaysToKeepの値を読み書きしているだけです。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 |
using Feedro.Model.Data; using Feedro.Model.Net; using System; using System.Collections.Generic; using Windows.Storage; namespace Feedro.ViewModel { public class GeneralSettingsViewModel : Monitorable { #region Constants private static readonly int[] _daysToKeepOptions = new int[] { 7, 14, 30, 60, 90, 180, 365 }; #endregion #region Properties public Store Store { get; private set; } public IReadOnlyCollection DaysToKeepOptions { get { return _daysToKeepOptions; } } public int SelectedDaysToKeep { get { return Store.DaysToKeep; } set { if (value == Store.DaysToKeep) return; Store.DaysToKeep = value; NotifyPropertyChanged(); } } #endregion #region .ctor public GeneralSettingsViewModel() { Store = new Store(); } #endregion } } |
ビュー
ビューに配置されているオブジェクトは、日数を選ぶためのComboBoxおよびそのラベルであるTextBlock(CaptionDaysToKeep)のみです。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 |
<SettingsFlyout x:Class="Feedro.View.GeneralSettingsFlyout" x:Uid="GeneralSettingsFlyout" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:local="using:Feedro.View" xmlns:vm="using:Feedro.ViewModel" IconSource="Assets/SmallLogo.png"> <SettingsFlyout.DataContext> <vm:GeneralSettingsViewModel /> </SettingsFlyout.DataContext> <StackPanel VerticalAlignment="Stretch" HorizontalAlignment="Stretch" > <StackPanel Style="{StaticResource SettingsFlyoutSectionStyle}"> <TextBlock x:Uid="CaptionDaysToKeep" Style="{StaticResource TitleTextBlockStyle}" Margin="0,0,0,10" /> <ComboBox ItemsSource="{Binding DaysToKeepOptions}" SelectedValue="{Binding SelectedDaysToKeep, Mode=TwoWay}" /> </StackPanel> </StackPanel> </SettingsFlyout> |
ComboBoxのItemsSource(選択可能なオプションの一覧)をビューモデルのDaysToKeepOptionsに、SelectedValue(選択された値)をビューモデルのSelectedDaysToKeepにバインドしておきます。SelectedDaysToKeepへのバインドは双方向になっているため、コンボボックスで日数を選択すると、その値が自動的にビューモデルのSelectedDaysToKeepプロパティに反映され、最終的にSettingsHelperを通じてアプリケーションの設定情報として保存されます。
設定チャームとの接続
設定画面ができたので、最後にこれを実際に設定チャームと接続してみます。設定チャームとして表示されるビューはWindows.UI.ApplicationSettings.SettingsPaneクラスのインスタンスです。まず、このビューに表示されるメニュー項目【一般】を追加します。SettingsPaneがビューの初期化を行う際、CommandsReuqestedイベントを発生させるので、そのタイミングでメニュー項目を追加します。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 |
sealed partial class App : Application { .... protected async override void OnLaunched(LaunchActivatedEventArgs args) { .... SettingsPane.GetForCurrentView().CommandsRequested += OnCommandsRequested; .... } private void OnCommandsRequested(SettingsPane sender, SettingsPaneCommandsRequestedEventArgs args) { UICommandInvokedHandler showSettingsPanel = (cmd) => { new GeneralSettingsFlyout().Show(); }; var loader = new ResourceLoader(); args.Request.ApplicationCommands.Clear(); args.Request.ApplicationCommands.Add( new SettingsCommand( "General", loader.GetString("CaptionGeneralSettings"), showSettingsPanel)); } .... } |
“General”というメニューの識別子、メニューラベルの文字列およびメニューが選択された場合の処理(showSettingsPanel)を登録しています。メニューが選択された場合の処理そのものは非常に簡単で、先ほど定義したビューのインスタンスを生成し、Showで表示しているだけです。