sourcetip

새로운 WPF의 User Settings / Application Settings 와 동등합니다.NET 버전

fileupload 2023. 4. 18. 23:16
반응형

새로운 WPF의 User Settings / Application Settings 와 동등합니다.NET 버전

. . . 또는 >=3.0을 사용하는 WPF 어플리케이션의 사용자 설정을 유지하기 위해 권장되는 방법은 무엇입니까?
는 어디에 있습니까?NET 사용자 설정이 사라졌습니까?

WPF 작성.Net Core 3.0 프로젝트 (VS2019 V16.3.1)
부동산이 없는 것을 확인했습니다.설정 섹션은 더 이상 없습니다.

[업데이트 2022: 포함]NET 6 그대로입니다]
[갱신 2023:.NET 7에서는 그대로입니다]

솔루션 탐색기

온라인 검색 후 마이크로소프트에 접속하기 시작했다.내선번호배열.

설정에 액세스하기 위한 코드가 비대해진 것 외에 더 나쁜 것은 -> 저장 안 함?
의 [사용자 설정(User Configuration Settings)NET 코어

다행인지 불행인지 마이크로소프트다.내선번호구성에서는 설계에 의한 저장을 지원하지 않습니다.이 Github 문제에 대한 자세한 내용은 Configuration Provider에 저장되지 않는 이유를 참조하십시오.


What is the prefered (and easy/fast/simple) way for persisting user settings for WPF applications with .Net Core >=3.0 / .NET5 / .NET6 / .NET7?
Before <= .Net 4.8 it was as easy as:
  • 변수를 속성에 추가합니다.사용자 설정

  • 시작 시 변수 읽기
    var culture = new CultureInfo(Properties.Settings.Default.LanguageSettings);

  • 변수가 변경되면 -> 즉시 저장합니다.
    Properties.Settings.Default.LanguageSettings = selected.TwoLetterISOLanguageName; Properties.Settings.Default.Save();

여기에 이미지 설명 입력

[ Properties ]-> [ Add - ]-> [ New Item ]오른쪽 버튼을 클릭해, 같은 낡은 정상적인 설정 파일을 추가하고, 「Settings」를 검색할 수 있습니다.이 파일은 설정 디자이너에서 편집하여 이전 .net 프레임워크 프로젝트에서와 같이 사용할 수 있습니다(ConfigurationManager, Settings).체납.업그레이드(), 설정.체납.보존등이 기능합니다).

또한 app.config 파일을 프로젝트 루트 폴더에 추가하고([Add] -> [ New Item ]에서와 같은 방법으로), 설정을 다시 저장한 후 프로젝트를 컴파일하면 출력 폴더에 .dll.config 파일이 있습니다.기존과 같이 기본 앱 값을 변경할 수 있습니다.

Visual Studio 1.16.3.5 및 .net core 3.0 WPF 프로젝트에서 테스트 완료.

참조한 투고에서 지적된 바와 같이 Microsoft.내선번호구성 API는 앱에 한 번만 설정되거나 최소한 읽기 전용으로 설정되는 것을 의미합니다.유저 설정을 간단하게/빠르게/심플하게 유지하는 것이 주된 목적이라면, 스스로 롤업 할 수 있습니다.설정 저장ApplicationData이전 API와 유사한 폴더입니다.

public class SettingsManager<T> where T : class
{
    private readonly string _filePath;

    public SettingsManager(string fileName)
    {
        _filePath = GetLocalFilePath(fileName);
    }

    private string GetLocalFilePath(string fileName)
    {
        string appData = Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData);
        return Path.Combine(appData, fileName);
    }

    public T LoadSettings() =>
        File.Exists(_filePath) ?
        JsonConvert.DeserializeObject<T>(File.ReadAllText(_filePath)) :
        null;

    public void SaveSettings(T settings)
    {
        string json = JsonConvert.SerializeObject(settings);
        File.WriteAllText(_filePath, json);
    }
}

가장 기본적인 것을 사용한 데모UserSettings

public class UserSettings
{
    public string Name { get; set; }
}

완전한 MVVM 예는 제공하지 않지만 메모리에는 인스턴스가 있습니다.참조_userSettings설정을 로드하면 데모의 기본 속성이 덮어쓰게 됩니다.물론 프로덕션에서는 시작 시 기본값을 제공하지 않습니다.이건 그냥 일러스트레이션의 목적일 뿐이에요.

public partial class MainWindow : Window
{
    private readonly SettingsManager<UserSettings> _settingsManager;
    private UserSettings _userSettings;

    public MainWindow()
    {
        InitializeComponent();

        _userSettings = new UserSettings() { Name = "Funk" };
        _settingsManager = new SettingsManager<UserSettings>("UserSettings.json");
    }

    private void Button_FromMemory(object sender, RoutedEventArgs e)
    {
        Apply(_userSettings);
    }

    private void Button_LoadSettings(object sender, RoutedEventArgs e)
    {
        _userSettings = _settingsManager.LoadSettings();
        Apply(_userSettings);
    }

    private void Button_SaveSettings(object sender, RoutedEventArgs e)
    {
        _userSettings.Name = textBox.Text;
        _settingsManager.SaveSettings(_userSettings);
    }

    private void Apply(UserSettings userSettings)
    {
        textBox.Text = userSettings?.Name ?? "No settings found";
    }
}

XAML

<Window x:Class="WpfApp.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
        xmlns:local="clr-namespace:WpfApp"
        mc:Ignorable="d"
        Title="MainWindow" Height="450" Width="800">
    <Window.Resources>
        <Style TargetType="Button">
            <Setter Property="Margin" Value="10"/>
        </Style> 
    </Window.Resources>
    <Grid Margin="10">
        <Grid.RowDefinitions>
            <RowDefinition/>
            <RowDefinition Height="Auto"/>
            <RowDefinition Height="Auto"/>
            <RowDefinition Height="Auto"/>
        </Grid.RowDefinitions>
        <TextBox Grid.Row="0" x:Name="textBox" Width="150" HorizontalAlignment="Center" VerticalAlignment="Center"/>
        <Button Grid.Row="1" Click="Button_FromMemory">From Memory</Button>
        <Button Grid.Row="2" Click="Button_LoadSettings">Load Settings</Button>
        <Button Grid.Row="3" Click="Button_SaveSettings">Save Settings</Button>
    </Grid>
</Window>

Nuget 패키지 시스템을 사용할 수 있습니다.설정컨피규레이션 매니저와 호환성이 있습니다.Net Standard 2.0이므로에서 사용할 수 있습니다.넷 코어 애플리케이션.

그에는 . 이 、 이 、 이 、 이 、 . 、 . 、 . . . . . . . . .그냥 코드를 카피할 수 있습니다.Settings.Designer.cs이 때 ㄴ, ㄴ, ㄴ, ㄴ, ㄴ, ㄴ, ㄴ, ㄴ, ㄴ, ㄴ, ㄴ, ㄴ, ㄴ, ㄴ.OnPropertyChangedSave.

여기서 예를 들어보겠습니다.Net Standard 프로젝트:

public class WatchConfig: ApplicationSettingsBase
{
    static WatchConfig _defaultInstance = (WatchConfig)Synchronized(new WatchConfig());

    public static WatchConfig Default { get => _defaultInstance; }

    protected override void OnPropertyChanged(object sender, PropertyChangedEventArgs e)
    {
        Save();
        base.OnPropertyChanged(sender, e);
    }

    [UserScopedSetting]
    [global::System.Configuration.DefaultSettingValueAttribute(
    @"<?xml    version=""1.0"" encoding=""utf-16""?>
    <ArrayOfString>
      <string>C:\temp</string>
     <string>..\otherdir</string>
     </ArrayOfString>")]
    public StringCollection Directories
    {
        get { return (StringCollection)this[nameof(Directories)]; }
        set { this[nameof(Directories)] = value; }
    }
}

인정된 답변에 대한 나의 개선은 기각되었으므로, 별도의 답변으로 여기 있습니다.

또, etc.nuget을 롤 할 .
디폴트로는 신규 작성 시 입니다.NET Core ™ 。NET5/6에서는 설정 섹션이 표시되지 않으므로 수동으로 추가해야 합니다.

<2023 업데이트>

Viacheslav가 설명한 바와 같이 버튼 클릭 한 번으로 해결 방법이 있습니다.프로젝트 속성을 열고 설정으로 이동하여 "응용 프로그램 설정 만들기 또는 열기" 링크를 클릭합니다.
VS 2022 및 .에서 테스트 완료

프로젝트 속성 설정

설명한 이전 수동 방법은 이 업데이트 아래 유지됩니다.

2023> </2023>


속성 이름 시 " " " "Properties폴더 아이콘이 약간 변경됩니다.

속성 폴더

이 새 속성 폴더를 마우스 오른쪽 버튼으로 클릭하고 새 항목을 추가합니다.

을 "Settings File"에서 "Settings File"로합니다.Settings1.settings로로 합니다.Settings.settings

설정 파일 추가

여기 있습니다.설정이 이미 돌아왔습니다.

설정 대화 상자

응용 프로그램컨피규레이션파일을 추가하여 출력 디렉토리에 .config 파일을 가져올 수 있습니다.

응용 프로그램 설정 파일 추가

Wpf Net용.핵심

프로젝트 마우스 오른쪽 버튼-> 새 항목 추가-> 설정 파일(일반)을 클릭합니다.

사용하다

Settings1.Default.Height = this.Height;
Settings1.Default.Width = this.Width;

this.Height = Settings1.Default.Height;
this.Width = Settings1.Default.Width;

Settings1.Default.Save();

여기서 'Settings1'은 파일 이름을 생성했습니다.

'설정 1'을 두 번 클릭합니다.설정 파일 및 편집

private void MainWindowRoot_SourceInitialized(object sender, EventArgs e)
{
    this.Top = Settings1.Default.Top;
    this.Left = Settings1.Default.Left;
    this.Height = Settings1.Default.Height;
    this.Width = Settings1.Default.Width;
    // Very quick and dirty - but it does the job
    if (Settings1.Default.Maximized)
    {
        WindowState = WindowState.Maximized;
    }
}

private void MainWindowRoot_Closing(object sender, System.ComponentModel.CancelEventArgs e)
{
    if (WindowState == WindowState.Maximized)
    {
        // Use the RestoreBounds as the current values will be 0, 0 and the size of the screen
        Settings1.Default.Top = RestoreBounds.Top;
        Settings1.Default.Left = RestoreBounds.Left;
        Settings1.Default.Height = RestoreBounds.Height;
        Settings1.Default.Width = RestoreBounds.Width;
        Settings1.Default.Maximized = true;
    }
    else
    {
        Settings1.Default.Top = this.Top;
        Settings1.Default.Left = this.Left;
        Settings1.Default.Height = this.Height;
        Settings1.Default.Width = this.Width;
        Settings1.Default.Maximized = false;
    }

    Settings1.Default.Save();
}

Funk의 답변을 바탕으로 SettingsManager에 대한 관리 기능을 일부 제거하고 추가 설정 클래스를 만들고 가능한 한 쉽게 사용할 수 있는 추상적인 일반 싱글톤 스타일의 바리에이션입니다.

[ Typeed Settings 클래스:

//Use System.Text.Json attributes to control serialization and defaults
public class MySettings : SettingsManager<MySettings>
{
    public bool SomeBoolean { get; set; }
    public string MyText { get; set; }
}

사용방법:

//Loading and reading values
MySettings.Load();
var theText = MySettings.Instance.MyText;
var theBool = MySettings.Instance.SomeBoolean;

//Updating values
MySettings.Instance.MyText = "SomeNewText"
MySettings.Save();

보시다시피 작성 및 사용할 줄의 수는 최소이며 파라미터가 없는 만큼 조금 더 견고합니다.

기본 클래스는 설정이 저장되는 위치를 정의하고 MySettings 하위 클래스당 하나의 설정 파일만 허용합니다. 어셈블리 및 클래스 이름이 위치를 결정합니다.속성 파일을 치환하기 위한 용도로는 이 정도면 충분합니다.

using System;
using System.IO;
using System.Linq;
using System.Reflection;

public abstract class SettingsManager<T> where T : SettingsManager<T>, new()
{
    private static readonly string filePath = GetLocalFilePath($"{typeof(T).Name}.json");

    public static T Instance { get; private set; }

    private static string GetLocalFilePath(string fileName)
    {
        string appData = Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData); 
        var companyName = Assembly.GetEntryAssembly().GetCustomAttributes<AssemblyCompanyAttribute>().FirstOrDefault();
        return Path.Combine(appData, companyName?.Company ?? Assembly.GetEntryAssembly().GetName().Name, fileName);
    }

    public static void Load()
    {
        if (File.Exists(filePath))
            Instance = System.Text.Json.JsonSerializer.Deserialize<T>(File.ReadAllText(filePath));
        else
            Instance = new T(); 
    }

    public static void Save()
    {
        string json = System.Text.Json.JsonSerializer.Serialize(Instance);
        Directory.CreateDirectory(Path.GetDirectoryName(filePath));
        File.WriteAllText(filePath, json);
    }
}

로 하고, 「」를 하면, 몇개의 이 있습니다.SettingsManager<T>.Instance로딩() 없이 사용할 수 있습니다.

버튼 클릭 한 번으로

프로젝트 => 속성 -> 리소스

프로젝트 리소스 설정

를 됩니다.Settings.settings일일에파이전과 마찬가지로 디자이너에게 개방됩니다.[(속성)]창에 표시되지 않게 되었습니다.

언급URL : https://stackoverflow.com/questions/56847571/equivalent-to-usersettings-applicationsettings-in-wpf-for-newer-net-versions

반응형