programing

C# - WPF 어플리케이션에 사용자 설정을 저장하는 방법

css3 2023. 4. 10. 22:10

C# - WPF 어플리케이션에 사용자 설정을 저장하는 방법

WPF 윈도(데스크탑) 어플리케이션에서 사용자 설정을 유지하려면 어떤 방법을 권장합니다.사용자는 실행 시 설정을 변경한 후 응용 프로그램을 종료할 수 있습니다.그러면 나중에 응용 프로그램을 시작할 때 현재 설정이 사용됩니다.실제로 응용 프로그램 설정은 변경되지 않은 것처럼 표시됩니다.

Q1 - 데이터베이스 또는 기타 접근법sqlite 데이터베이스를 사용할 예정이므로 데이터베이스 내의 테이블을 사용하는 것이 어떤 접근법보다 좋습니까?

Q2 - 다른 데이터 "Da" 등)string,long,DateTimeetc) 및 이 있는 .etc )。첫 번째가 더 편할 것 같은데, 설정이 많지 않으면 오버헤드가 별로 안 나요?

Q3 - 어플리케이션 설정을 사용할 수 있습니까?이 경우 여기서 지속성을 활성화하기 위해 필요한 특별한 작업이 있습니까?또한 이 경우 애플리케이션 설정 디자이너에서 "기본값"을 사용할 경우 어떻게 됩니까?디폴트는 어플리케이션 실행 사이에 저장된 설정을 덮어쓰나요?(또는 기본값을 사용하지 않을 필요가 있습니까?)

이것에 애플리케이션 설정을 사용할 수 있습니다.데이터베이스를 사용하는 것은, 설정(특히 Web 서비스를 사용하는 경우)을 읽고 쓰는 데 걸리는 시간을 고려하면, 최적인 옵션이 아닙니다.

이를 실현하고 WPF에서 사용하는 방법을 설명하는 링크는 다음과 같습니다.

WPF에서의 사용자 설정

간단한 WPF 힌트: WPF 응용 프로그램 리소스 및 설정에 바인드하는 방법

WPF 설정 가능한 창

업데이트: 요즘은 JSON을 사용하고 있습니다.

은 대부분의 합니다.XML 을 사용합니다..ApplicationSettings빌트인(built-in)에는 몇 가지 제약이 있고, (나에게는) 저장 장소에 정의되어 있지만 매우 이상한 동작이 있습니다.★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★그러나 저장 방법과 위치를 완전히 제어하려면 다른 방법을 사용합니다.

  1. 당신의 모든 설정으로 어딘가에서 클래스를 만듭니다.는 그것을 가가라고 했다.MySettings
  2. 지속성을 위한 저장 및 읽기 구현
  3. 어플리케이션 코드로 사용

장점:

  • 매우 심플한 어프로치.
  • 설정에 대한 클래스 1개장전, 저장
  • 모든 설정이 안전합니다.
  • 로직을 심플화 또는 필요에 따라 확장할 수 있습니다(버전, 사용자당 다수의 프로파일 등).
  • 어떤 경우에도 매우 잘 작동합니다(데이터베이스, 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.DefaultWPF에 을 합니다.Settings.

할 때 하려면 을 하십시오.Settings 및 " " "Deserialize되는 타입 「」에 T해야 합니다.type to (type type to ( type to ( type ) 。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);
        }

데이터베이스 외에 사용자 관련 설정을 저장하는 다음 옵션도 사용할 수 있습니다.

  1. 「」의 HKEY_CURRENT_USER

  2. AppData 표시

  3. 를 사용합니다.SettingsWPF 및 그 로 .

제 경험상 모든 설정을 데이터베이스 테이블에 저장하는 것이 가장 좋은 해결책입니다.퍼포먼스도 걱정하지 마세요.오늘날의 데이터베이스는 빠르고 한 테이블에 수천 개의 열을 쉽게 저장할 수 있습니다.나는 악몽을 꾸기 전에 이것을 힘들게 배웠다.로컬 파일이나 레지스트리에 저장하는 것은 하나의 큰 문제가 있습니다.앱을 지원해야 하고 컴퓨터가 꺼져 있는 경우 - 사용자가 앞에 있지 않은 경우 - 할 수 있는 일이 없습니다. - 설정이 DB에 있는 경우 - 설정을 변경할 수 있으며 설정을 비교할 수 있는 것은 말할 것도 없습니다.

SQLite는 작고 빠른 자체 포함 전체 기능을 갖춘 SQL 데이터베이스 엔진입니다.저는 개인적으로 설정 파일과 XML 파일 접근 방식을 시도해 보고 추천합니다.

NuGet 패키지 시스템을 설치합니다.Data.SQLite는 ADO입니다.SQLite용 NET 공급자.이 패키지에는 LINQ 및 엔티티 프레임워크에 대한 지원이 포함되어 있습니다.전체적으로 이러한 지원 기능을 사용하여 설정 창에서 많은 작업을 수행할 수 있습니다.

1. SQLite 2.를 설치합니다.데이터베이스 파일 3을 만듭니다.테이블을 생성하여 설정을 저장합니다.4 .응용 프로그램의 데이터베이스 파일에 액세스하여 설정을 읽고 편집합니다.

데이터베이스를 조정할 수 있고 ADO를 활용할 수 있기 때문에 애플리케이션 설정에 매우 도움이 된다고 느꼈습니다.네트워크 및 LINQ 기능

는 보통 관습]을 하여 이런 .Serializable ] disk]를 선택합니다.이 경우 SQLite 데이터베이스에 문자열 BLOB처럼 쉽게 저장할 수 있습니다.

  1. 제가 일한 모든 곳에서 애플리케이션 지원 때문에 데이터베이스가 필수적이었습니다.Adam이 말한 것처럼 사용자가 자리에 없거나 컴퓨터가 꺼져 있을 수 있습니다.또한 다른 사용자의 구성을 빠르게 변경하거나 신규 가입자에게 기본(또는 팀원) 구성을 할당해야 할 수도 있습니다.

  2. 응용 프로그램의 새 버전이 출시됨에 따라 설정이 커질 가능성이 높은 경우 데이터를 블럽으로 저장하여 응용 프로그램에 의해 역직렬화할 수 있습니다.이것은 모듈을 검출하는 프리즘과 같은 것을 사용하는 경우에 특히 유용합니다.모듈이 어떤 설정을 반환할지 알 수 없기 때문입니다.BLOB는 사용자 이름/머신 복합 키로 키를 지정할 수 있습니다.이렇게 하면 기계마다 다른 설정을 할 수 있습니다.

  3. 빌트 설정 클래스는 별로 사용하지 않았기 때문에 코멘트는 삼가겠습니다.:)

VB.net 데스크톱 WPF 응용 프로그램의 클래스에 기반한 xml 제어 파일을 사용하고 싶습니다.이 모든 것을 하나로 하기 위한 위의 코드는 훌륭하며, 나를 올바른 방향으로 인도해 줍니다.VB.net 솔루션을 찾고 있는 사람이 있는 경우, 제가 작성한 클래스는 다음과 같습니다.

Imports System.IO
Imports System.Xml.Serialization

Public Class XControl

Private _person_ID As Integer
Private _person_UID As Guid

'load from file
Public Function XCRead(filename As String) As XControl
    Using sr As StreamReader = New StreamReader(filename)
        Dim xmls As New XmlSerializer(GetType(XControl))
        Return CType(xmls.Deserialize(sr), XControl)
    End Using
End Function

'save to file
Public Sub XCSave(filename As String)
    Using sw As StreamWriter = New StreamWriter(filename)
        Dim xmls As New XmlSerializer(GetType(XControl))
        xmls.Serialize(sw, Me)
    End Using
End Sub

'all the get/set is below here

Public Property Person_ID() As Integer
    Get
        Return _person_ID
    End Get
    Set(value As Integer)
        _person_ID = value
    End Set
End Property

Public Property Person_UID As Guid
    Get
        Return _person_UID
    End Get
    Set(value As Guid)
        _person_UID = value
    End Set
End Property

End Class

언급URL : https://stackoverflow.com/questions/3784477/c-sharp-approach-for-saving-user-settings-in-a-wpf-application