Подтвердить что ты не робот

Добавление класса настроек в приложение UWP

Я разрабатываю приложение Universal Platform для Windows, но в Visual Studio нет шаблона настроек.

Как я могу реализовать простой, строго типизированный и наблюдаемый класс, который хранит мои настройки в LocalSettings или RoamingSettings?

4b9b3361

Ответ 1

  • Создайте новый класс, наследующий от ObservableSettings.
  • Вызов в конструктор базового класса, указывающий, хотите ли вы сохранить настройки в Локальные настройки или в Роуминг-настройки.
  • Добавьте все свои свойства, вызывающие членов базового класса Установите и Получить в получателе и в сеттере. Не нужно передавать имя свойства или использовать оператор nameof()!
  • При желании вы можете установить значение по умолчанию, украсив свойство атрибутом 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>

Все будет храниться правильно в вашем репозитории настроек.

Здесь у вас есть реализация DefaultSettingValue и ObservableSettings:

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.