web-dev-qa-db-ja.com

UWPアプリへの設定クラスの追加

ユニバーサルWindowsプラットフォームアプリを開発していますが、VisualStudioに設定テンプレートがありません。

LocalSettingsまたはRoamingSettingsに設定を保存する簡単で強く型付けされた監視可能なクラスを実装するにはどうすればよいですか?

42
joseangelmt
  1. ObservableSettingsから継承する新しいクラスを作成します。
  2. 設定をLocalSettingsに保存するかRoamingSettingsに保存するかを示す基本クラスコンストラクターを呼び出します。
  3. 基本クラスのメンバーSetおよびGetを呼び出すすべてのプロパティをゲッターとセッターに追加します。プロパティの名前を渡したり、nameof()演算子を使用したりする必要はありません!
  4. オプションで、プロパティを装飾するデフォルト値をDefaultSettingValue属性で設定できます。

設定クラスの例を次に示します。

namespace Test
{
    public class Settings : ObservableSettings
    {
        private static Settings settings = new Settings();
        public static Settings Default
        {
            get { return settings; }
        }

        public Settings()
            : base(ApplicationData.Current.LocalSettings)
        {
        }

        [DefaultSettingValue(Value = 115200)]
        public int Bauds
        {
            get { return Get<int>(); }
            set { Set(value); }
        }

        [DefaultSettingValue(Value = "Jose")]
        public string Name
        {
            get { return Get<string>(); }
            set { Set(value); }
        }

    }
}

そしてここであなたのapp.xamlにインスタンスを追加する方法:

<Application
    x:Class="Test.App"
    xmlns="http://schemas.Microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.Microsoft.com/winfx/2006/xaml"
    xmlns:local="using:Test"
    RequestedTheme="Light">
    <Application.Resources>
        <local:Settings x:Key="settings"/>
    </Application.Resources>
</Application>

MVVM方式で値にアクセスして変更します。

<Page
    x:Class="Test.MainPage"
    xmlns="http://schemas.Microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.Microsoft.com/winfx/2006/xaml"
    xmlns:local="using:Test"
    xmlns:d="http://schemas.Microsoft.com/expression/blend/2008"
    xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
    mc:Ignorable="d"
    DataContext="{StaticResource settings}">

    <StackPanel Background="{ThemeResource ApplicationPageBackgroundThemeBrush}">
        <TextBlock Text="Bauds"/>
        <TextBox Text="{Binding Default.Bauds, Mode=TwoWay}"/>
        <TextBlock Text="Name"/>
        <TextBox Text="{Binding Default.Name, Mode=TwoWay}"/>
    </StackPanel>
</Page>

すべてが設定リポジトリに適切に保存されます。

ここにDefaultSettingValueObservableSettingsの実装があります:

using System.Collections.Generic;
using System.Linq;
using System.Runtime.CompilerServices;
using System.Reflection;
using System.ComponentModel;
using Windows.Storage;


[AttributeUsage(AttributeTargets.Property, AllowMultiple = false)]
public sealed class DefaultSettingValueAttribute : Attribute
{
    public DefaultSettingValueAttribute()
    {
    }

    public DefaultSettingValueAttribute(object value)
    {
        Value = value;
    }

    public object Value { get; set; }
}

public class ObservableSettings : INotifyPropertyChanged
{
    private readonly ApplicationDataContainer settings;

    public ObservableSettings(ApplicationDataContainer settings)
    {
        this.settings = settings;
    }

    public event PropertyChangedEventHandler PropertyChanged;

    protected bool Set<T>(T value, [CallerMemberName] string propertyName = null)
    {
        if (settings.Values.ContainsKey(propertyName))
        {
            var currentValue = (T)settings.Values[propertyName];
            if (EqualityComparer<T>.Default.Equals(currentValue, value))
                return false;
        }

        settings.Values[propertyName] = value;
        PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
        return true;
    }

    protected T Get<T>([CallerMemberName] string propertyName = null)
    {
        if (settings.Values.ContainsKey(propertyName))
            return (T)settings.Values[propertyName];

        var attributes = GetType().GetTypeInfo().GetDeclaredProperty(propertyName).CustomAttributes.Where(ca => ca.AttributeType == typeof(DefaultSettingValueAttribute)).ToList();
        if (attributes.Count == 1)
            return (T)attributes[0].NamedArguments[0].TypedValue.Value;

        return default(T);
    }

GitHub で作成したリポジトリから、機能例を含むソリューションをダウンロードできます。

54
joseangelmt