[c#] WPF 응용 프로그램에서 사용자 설정을 저장하는 방법?



Answers

설정 정보를 XML StringsSettings.Default 저장할 수 있습니다. 구성 데이터를 저장할 클래스를 몇 개 만들고 [Serializable] 인지 확인하십시오. 다음 헬퍼를 사용하면 이러한 객체의 인스턴스 ( List<T> 또는 배열 T[] 등)를 String serialize 할 수 있습니다. 이 다양한 문자열 각각을 WPF 응용 프로그램 Settings.Default 의 자체 Settings.Default 슬롯에 저장하십시오.

다음에 앱이 시작될 때 개체를 복구하려면 관심있는 Settings 문자열을 읽고 원하는 형식 T Deserialize 하십시오 (이 시간은 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);
}
Question

WPF 윈도우 (데스크톱) 응용 프로그램에서 사용자 설정을 지속하기 위해 어떤 접근 방식을 권장합니까? 사용자가 런타임에 설정을 변경 한 다음 응용 프로그램을 닫을 수 있고 나중에 응용 프로그램을 시작할 때 응용 프로그램이 현재 설정을 사용한다는 아이디어가 있습니다. 그러면 응용 프로그램 설정이 변경되지 않는 것처럼 효과적으로 나타납니다.

Q1 - 데이터베이스 또는 다른 접근법? 내가 어쨌든 데이터베이스에서 테이블을 사용하여 어떤 접근 방식으로 좋을 것이 사용됩니다 sqlite 데이터베이스가 있나요?

Q2 - 데이터베이스 인 경우 : 어떤 데이터베이스 테이블 디자인입니까? 하나의 테이블 (예 : string , long , DateTime 등) 또는 값을 직렬화 및 비 직렬화해야하는 값에 대한 문자열이있는 테이블을 가질 수있는 다른 데이터 유형에 대한 열이 있습니까? 첫 번째 것이 더 쉬울 것이라고 생각하고, 많은 설정이 없으면 오버 헤드가별로 없습니까?

Q3 - 응용 프로그램 설정을이 용도로 사용할 수 있습니까? 그렇다면 여기에 지속성을 활성화하는 데 필요한 특별한 작업이 있습니까? 또한이 경우 응용 프로그램 설정 디자이너에서 "기본값"값 사용과 관련하여 어떤 일이 발생합니까? 기본값은 응용 프로그램 실행 사이에 저장된 모든 설정을 무시합니까? (또는 기본값을 사용하지 않아도됩니다)




내 경험에 의하면 데이터베이스 테이블의 모든 설정을 저장하는 것이 가장 좋은 방법입니다. 성능에 대해 걱정하지 마십시오. 오늘날의 데이터베이스는 빠르고 테이블에 수천 개의 열을 쉽게 저장할 수 있습니다. 나는 이것을 힘든 방법으로 배웠습니다 - 제가 항복 / 탈 직렬화되기 전에 - 악몽이었습니다. 로컬 파일이나 레지스트리에 저장하는 것은 큰 문제가 있습니다. 앱을 지원해야하고 컴퓨터가 꺼져있는 경우 사용자가 앞에 있지 않습니다. 설정이 DB에있는 경우 수행 할 수있는 작업이 없습니다. 당신이 설정을 비교할 수 있다고 언급하지 않기 위해 그들과 비올라를 변경 ....




이 질문에 대한 장기적으로 가장 일반적인 접근 방식은 다음과 같습니다. Isolated Storage.

컨트롤 상태를 XML 또는 다른 형식으로 serialize 한 다음 (특히 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);
        }



  1. 내가 일한 모든 곳에서 애플리케이션 지원으로 인해 데이터베이스가 필수적이었습니다. Adam의 말처럼 사용자가 책상에 앉아 있지 않거나 컴퓨터가 꺼져 있거나 다른 사람의 구성을 신속하게 변경하거나 새 대화 상대에게 기본 (또는 팀 구성원) 구성을 할당 할 수 있습니다.

  2. 응용 프로그램의 새 버전이 릴리스 될 때 설정이 증가 할 가능성이있는 경우 데이터를 모양으로 저장하여 응용 프로그램에서 직렬화 할 수 있습니다. 모듈이 반환 할 설정을 알 수 없으므로 모듈을 검색하는 Prism과 같은 것을 사용하는 경우 특히 유용합니다. blob은 사용자 이름 / 기계 복합 키에 의해 입력 될 수 있습니다. 그렇게하면 모든 컴퓨터에 대해 다른 설정을 할 수 있습니다.

  3. 내가 내장 된 설정 클래스를 많이 사용하지 않았으므로 주석을 쓰지 않을 것입니다. :)




Related