- 設定が変更される都度、保存するようにした方が確実。
- 永続的にするにはApplicationDataのLocalSettingsかRoamingSettingsに保存するのが便利。
- 設定用クラスの設定用プロパティのアクセサー内でこれらにアクセスするようにすると管理がすっきりする。
- そもそもLocalSettingsかRoamingSettingsを設定用プロパティのバッキングストアにしてしまえばいい。
この方法をベースに自作列挙型や自作クラスも保存できるように考えて、以下のようになりました。まずは設定用の基本クラス。
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
using System; | |
using System.ComponentModel; | |
using System.Diagnostics; | |
using System.IO; | |
using System.Reflection; | |
using System.Runtime.CompilerServices; | |
using System.Runtime.Serialization; | |
using System.Runtime.Serialization.Json; | |
using Windows.Foundation.Collections; | |
using Windows.Storage; | |
public abstract class SettingsBase : INotifyPropertyChanged | |
{ | |
protected enum ContainerType | |
{ | |
Local, // Default | |
Roaming, | |
} | |
protected static T GetValue<T>(ContainerType container = default(ContainerType), [CallerMemberName] string propertyName = null) | |
{ | |
return GetValue(default(T), container, propertyName); | |
} | |
protected static T GetValue<T>(T defaultValue, ContainerType container = default(ContainerType), [CallerMemberName] string propertyName = null) | |
{ | |
try | |
{ | |
var values = GetSettingsValues(container); | |
if (values.ContainsKey(propertyName)) | |
{ | |
if (typeof(T).GetTypeInfo().GetCustomAttribute(typeof(DataContractAttribute)) != null) | |
{ | |
using (var ms = new MemoryStream()) | |
using (var sw = new StreamWriter(ms)) | |
{ | |
sw.Write(values[propertyName]); | |
sw.Flush(); | |
ms.Seek(0, SeekOrigin.Begin); | |
var serializer = new DataContractJsonSerializer(typeof(T)); | |
return (T)serializer.ReadObject(ms); | |
} | |
} | |
return (T)values[propertyName]; | |
} | |
} | |
catch (Exception ex) | |
{ | |
Debug.WriteLine("Failed to get property value: {0}\r\n{1}", propertyName, ex); | |
} | |
return defaultValue; | |
} | |
protected static void SetValue<T>(T propertyValue, ContainerType container = default(ContainerType), [CallerMemberName] string propertyName = null) | |
{ | |
try | |
{ | |
var values = GetSettingsValues(container); | |
if (typeof(T).GetTypeInfo().IsEnum) | |
{ | |
var underlyingValue = Convert.ChangeType(propertyValue, Enum.GetUnderlyingType(typeof(T))); | |
if (values.ContainsKey(propertyName)) | |
values[propertyName] = underlyingValue; | |
else | |
values.Add(propertyName, underlyingValue); | |
return; | |
} | |
if (typeof(T).GetTypeInfo().GetCustomAttribute(typeof(DataContractAttribute)) != null) | |
{ | |
using (var ms = new MemoryStream()) | |
using (var sr = new StreamReader(ms)) | |
{ | |
var serializer = new DataContractJsonSerializer(typeof(T)); | |
serializer.WriteObject(ms, propertyValue); | |
ms.Seek(0, SeekOrigin.Begin); | |
var serializedValue = sr.ReadToEnd(); | |
if (values.ContainsKey(propertyName)) | |
values[propertyName] = serializedValue; | |
else | |
values.Add(propertyName, serializedValue); | |
} | |
return; | |
} | |
if (values.ContainsKey(propertyName)) | |
values[propertyName] = propertyValue; | |
else | |
values.Add(propertyName, propertyValue); | |
} | |
catch (Exception ex) | |
{ | |
Debug.WriteLine("Failed to set property value: {0}\r\n{1}", propertyName, ex); | |
} | |
} | |
private static IPropertySet GetSettingsValues(ContainerType container) | |
{ | |
return (container == ContainerType.Local) | |
? ApplicationData.Current.LocalSettings.Values | |
: ApplicationData.Current.RoamingSettings.Values; | |
} | |
#region INotifyPropertyChanged member | |
public event PropertyChangedEventHandler PropertyChanged; | |
protected void OnPropertyChanged([CallerMemberName] string propertyName = null) | |
{ | |
var handler = PropertyChanged; | |
if (handler != null) | |
handler(this, new PropertyChangedEventArgs(propertyName)); | |
} | |
#endregion | |
} |
これを継承した設定用クラスの例。
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
using Windows.Foundation; | |
public class Settings : SettingsBase | |
{ | |
private Settings() | |
{ } | |
public static Settings Current | |
{ | |
get { return _current; } | |
} | |
private static readonly Settings _current = new Settings(); | |
public Point StartLocation | |
{ | |
get { return GetValue<Point>(ContainerType.Roaming); } | |
set { SetValue(value, ContainerType.Roaming); } | |
} | |
public int DestinationCount | |
{ | |
get { return GetValue<int>(10, ContainerType.Roaming); } | |
set | |
{ | |
SetValue(value, ContainerType.Roaming); | |
OnPropertyChanged(); | |
} | |
} | |
public string[] DestinationNames | |
{ | |
get { return GetValue<string[]>(ContainerType.Roaming); } | |
set | |
{ | |
SetValue(value, ContainerType.Roaming); | |
OnPropertyChanged(); | |
} | |
} | |
public TravelMethod Method | |
{ | |
get { return GetValue<TravelMethod>(); } | |
set { SetValue(value); } | |
} | |
public TravelSchedule Schedule | |
{ | |
get { return GetValue<TravelSchedule>(); } | |
set { SetValue(value); } | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
public enum TravelMethod | |
{ | |
Foot, | |
Bus, | |
Train, | |
Airplane, | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
using System; | |
using System.Runtime.Serialization; | |
[DataContract] | |
public class TravelSchedule | |
{ | |
[DataMember] | |
public string DestinationName { get; set; } | |
[DataMember] | |
public DateTime DepatureTime { get; set; } | |
} |
とくに目新しいことはないですが、一つの定型的方法として。
[修正]
GetValueメソッド中で自作クラスの値がまだ存在しなかった場合の処理を修正。
0 コメント :
コメントを投稿