WPF Windows (데스크톱) 애플리케이션에서 사용자 설정을 유지하기 위해 어떤 접근 방식을 권장합니까? 아이디어는 사용자가 런타임에 설정을 변경 한 다음 응용 프로그램을 닫을 수 있으며 나중에 응용 프로그램을 시작할 때 응용 프로그램이 현재 설정을 사용할 수 있다는 것입니다. 실제로 응용 프로그램 설정이 변경되지 않는 것처럼 나타납니다.
Q1-데이터베이스 또는 기타 접근 방식? 어쨌든 사용할 sqlite 데이터베이스가 있으므로 데이터베이스에서 테이블을 사용하는 것이 모든 접근 방식만큼 좋을까요?
Q2-If Database : 어떤 데이터베이스 테이블 디자인입니까? 하나가있을 수 있음을 다른 데이터 형식의 열이 하나 개의 테이블 (예를 들면 string
, long
, DateTime
등) 또는 당신이 직렬화 및 역 직렬화 값으로이있는시 값에 대한 문자열을 그냥 테이블? 첫 번째가 더 쉬울 것이라고 생각하고 설정이 많지 않으면 오버 헤드가 많지 않습니까?
Q3-이를 위해 응용 프로그램 설정을 사용할 수 있습니까? 그렇다면 여기에서 지속성을 활성화하는 데 필요한 특별한 작업이 있습니까? 또한이 경우 응용 프로그램 설정 디자이너의 “기본값”값 사용과 관련하여 어떤 일이 발생합니까? 기본값이 응용 프로그램 실행 사이에 저장된 모든 설정을 무시합니까? (또는 기본값을 사용하지 않아도됩니다)
답변
이를 위해 응용 프로그램 설정 을 사용할 수 있습니다. 데이터베이스를 사용하는 것은 설정을 읽고 쓰는 데 걸리는 시간을 고려할 때 최선의 선택이 아닙니다 (특히 웹 서비스를 사용하는 경우).
다음은이를 달성하고 WPF에서 사용하는 방법을 설명하는 몇 가지 링크입니다.
빠른 WPF 팁 : WPF 애플리케이션 리소스 및 설정에 바인딩하는 방법은 무엇입니까?
답변
업데이트 : 요즘은 JSON을 사용합니다.
또한 파일 직렬화를 선호합니다. XML 파일은 대부분 모든 요구 사항에 적합합니다. ApplicationSettings
빌드를 사용할 수 있지만 여기에는 몇 가지 제한 사항과 정의되었지만 (저에게는) 저장 위치에 매우 이상한 동작이 있습니다. 나는 그것들을 많이 사용했고 그들은 작동합니다. 그러나 저장 방법과 위치를 완전히 제어하려면 다른 접근 방식을 사용합니다.
- 모든 설정으로 어딘가에 수업을 만드십시오. 나는 그것을 명명했다
MySettings
- 지속성을 위해 저장 및 읽기 구현
- 응용 프로그램 코드에서 사용
장점 :
- 매우 간단한 접근 방식입니다.
- 설정을위한 하나의 클래스. 하중. 저장.
- 모든 설정은 유형이 안전합니다.
- 논리를 단순화하거나 필요에 맞게 확장 할 수 있습니다 (버전 관리, 사용자 당 여러 프로필 등).
- 어떤 경우에도 매우 잘 작동합니다 (데이터베이스, WinForms, WPF, 서비스 등).
- XML 파일을 저장할 위치를 정의 할 수 있습니다.
- 코드 또는 수동으로 찾아서 조작 할 수 있습니다.
- 내가 상상할 수있는 모든 배포 방법에서 작동합니다.
단점 :-설정 파일을 저장할 위치를 생각해야합니다. (하지만 설치 폴더 만 사용할 수 있습니다.)
다음은 간단한 예입니다 (테스트되지 않음).
public class MySettings
{
public string Setting1 { get; set; }
public List<string> Setting2 { get; set; }
public void Save(string filename)
{
using (StreamWriter sw = new StreamWriter(filename))
{
XmlSerializer xmls = new XmlSerializer(typeof(MySettings));
xmls.Serialize(sw, this);
}
}
public MySettings Read(string filename)
{
using (StreamReader sw = new StreamReader(filename))
{
XmlSerializer xmls = new XmlSerializer(typeof(MySettings));
return xmls.Deserialize(sw) as MySettings;
}
}
}
그리고 그것을 사용하는 방법이 있습니다. 사용자 설정이 있는지 확인하여 기본값을로드하거나 사용자 설정으로 재정의 할 수 있습니다.
public class MyApplicationLogic
{
public const string UserSettingsFilename = "settings.xml";
public string _DefaultSettingspath =
Assembly.GetEntryAssembly().Location +
"\\Settings\\" + UserSettingsFilename;
public string _UserSettingsPath =
Assembly.GetEntryAssembly().Location +
"\\Settings\\UserSettings\\" +
UserSettingsFilename;
public MyApplicationLogic()
{
// if default settings exist
if (File.Exists(_UserSettingsPath))
this.Settings = Settings.Read(_UserSettingsPath);
else
this.Settings = Settings.Read(_DefaultSettingspath);
}
public MySettings Settings { get; private set; }
public void SaveUserSettings()
{
Settings.Save(_UserSettingsPath);
}
}
누군가이 접근 방식에서 영감을 얻었을 수도 있습니다. 이것이 제가 수년 동안하는 방식이며 저는 그것에 대해 매우 만족합니다.
답변
설정 정보 Strings
를 XML 형식으로 Settings.Default
. 구성 데이터를 저장할 몇 가지 클래스를 만들고 [Serializable]
. 그런 다음 다음 도우미를 사용하여 이러한 개체의 인스턴스 List<T>
(또는 배열 T[]
등)를 String
. 이러한 다양한 문자열 각각을 Settings.Default
WPF 애플리케이션의 Settings
.
다음에 앱이 시작될 때 객체를 복구하려면 Settings
관심 있는 문자열과 Deserialize
예상 유형을 읽습니다 T
(이번에는에 대한 유형 인수로 명시 적으로 지정되어야 함 Deserialize<T>
).
public static String Serialize<T>(T t)
{
using (StringWriter sw = new StringWriter())
using (XmlWriter xw = XmlWriter.Create(sw))
{
new XmlSerializer(typeof(T)).Serialize(xw, t);
return sw.GetStringBuilder().ToString();
}
}
public static T Deserialize<T>(String s_xml)
{
using (XmlReader xw = XmlReader.Create(new StringReader(s_xml)))
return (T)new XmlSerializer(typeof(T)).Deserialize(xw);
}
답변
이 질문에 대한 장기 실행 중 가장 일반적인 접근 방식은 격리 된 저장소입니다.
컨트롤 상태를 XML 또는 다른 형식으로 직렬화 한 다음 (특히 WPF로 종속성 속성을 저장하는 경우 쉽게) 파일을 사용자의 격리 된 저장소에 저장합니다.
앱 설정 경로로 가고 싶다면 한 지점에서 비슷한 것을 시도했지만 아래 접근 방식은 격리 된 저장소를 사용하도록 쉽게 조정할 수 있습니다.
class SettingsManager
{
public static void LoadSettings(FrameworkElement sender, Dictionary<FrameworkElement, DependencyProperty> savedElements)
{
EnsureProperties(sender, savedElements);
foreach (FrameworkElement element in savedElements.Keys)
{
try
{
element.SetValue(savedElements[element], Properties.Settings.Default[sender.Name + "." + element.Name]);
}
catch (Exception ex) { }
}
}
public static void SaveSettings(FrameworkElement sender, Dictionary<FrameworkElement, DependencyProperty> savedElements)
{
EnsureProperties(sender, savedElements);
foreach (FrameworkElement element in savedElements.Keys)
{
Properties.Settings.Default[sender.Name + "." + element.Name] = element.GetValue(savedElements[element]);
}
Properties.Settings.Default.Save();
}
public static void EnsureProperties(FrameworkElement sender, Dictionary<FrameworkElement, DependencyProperty> savedElements)
{
foreach (FrameworkElement element in savedElements.Keys)
{
bool hasProperty =
Properties.Settings.Default.Properties[sender.Name + "." + element.Name] != null;
if (!hasProperty)
{
SettingsAttributeDictionary attributes = new SettingsAttributeDictionary();
UserScopedSettingAttribute attribute = new UserScopedSettingAttribute();
attributes.Add(attribute.GetType(), attribute);
SettingsProperty property = new SettingsProperty(sender.Name + "." + element.Name,
savedElements[element].DefaultMetadata.DefaultValue.GetType(), Properties.Settings.Default.Providers["LocalFileSettingsProvider"], false, null, SettingsSerializeAs.String, attributes, true, true);
Properties.Settings.Default.Properties.Add(property);
}
}
Properties.Settings.Default.Reload();
}
}
…..과….
Dictionary<FrameworkElement, DependencyProperty> savedElements = new Dictionary<FrameworkElement, DependencyProperty>();
public Window_Load(object sender, EventArgs e) {
savedElements.Add(firstNameText, TextBox.TextProperty);
savedElements.Add(lastNameText, TextBox.TextProperty);
SettingsManager.LoadSettings(this, savedElements);
}
private void Window_Closing(object sender, System.ComponentModel.CancelEventArgs e)
{
SettingsManager.SaveSettings(this, savedElements);
}
답변
데이터베이스와 별도로 사용자 관련 설정을 저장하기 위해 다음 옵션을 사용할 수도 있습니다.
-
아래에 레지스트리
HKEY_CURRENT_USER
-
AppData
폴더 의 파일 -
Settings
WPF에서 파일을 사용 하고 범위를 사용자로 설정하여
답변
내 경험상 모든 설정을 데이터베이스 테이블에 저장하는 것이 최상의 솔루션입니다. 성능에 대해 걱정하지 마십시오. 오늘날의 데이터베이스는 빠르며 테이블에 수천 개의 열을 쉽게 저장할 수 있습니다. 나는 이것을 어려운 방법으로 배웠다-내가 serilizing / deserializing하기 전에-악몽. 로컬 파일이나 레지스트리에 저장하는 것은 한 가지 큰 문제가 있습니다. 앱을 지원해야하고 컴퓨터가 꺼져있는 경우-사용자가 앞에 있지 않은 경우-할 수있는 일이 없습니다 …. 설정이 DB에 있으면 가능합니다. 설정을 비교할 수 있다는 것은 말할 것도없고 비올라와 변경했습니다 ….
답변
저는 일반적으로 사용자 정의 [ Serializable
] 설정 클래스를 정의 하고 단순히 디스크에 직렬화하여 이러한 종류의 작업을 수행합니다 . 귀하의 경우에는 SQLite 데이터베이스에 문자열 blob으로 쉽게 저장할 수 있습니다.