简体   繁体   English

调用Properties.Settings.Default.Saved()后,为什么我的用户设置没有保留?

[英]Why are my user-settings not persisted after calling Properties.Settings.Default.Saved()?

This is just for demo purposes. 这仅用于演示目的。 I will not actually cache passwords this way as I've received advice that Application Settings is not secure. 我实际上不会以这种方式缓存密码,因为我收到了应用程序设置不安全的建议。

Problem Statement 问题陈述

I'm creating a login Windows Forms application that persists the string values entered into the Name and Password fields between application sessions using Application Settings . 我正在创建一个登录Windows窗体应用程序,该应用程序使用应用程序设置在应用程序会话之间保留输入到NamePassword字段中的字符串值。 The form should load the Name and Password values that was entered from the previous session. 表单应加载从上一个会话输入的NamePassword值。

I ran into a problem where the fields fail to get saved and reloaded if I use Properties.Settings.Default.Save() to save those field values from a private method: 我遇到了一个问题,如果我使用Properties.Settings.Default.Save()从私有方法保存这些字段值,则字段无法保存并重新加载:

    // Save the current values of each field
    private void SaveSettings()
    {
        Properties.Settings.Default.Name = textBox1.Text;
        Properties.Settings.Default.Password = textBox2.Text;
        Properties.Settings.Default.Save();
    }

When the field values change, this is how `SaveSettings() would be called: 当字段值改变时,这就是调用SaveSettings()的方式:

    // Saves ALL field values in the form whenever the field changes. 
    // Warning: This function gets called each time a character is added to the 'Name' field.
    private void textBox1_TextChanged(object sender, EventArgs e)
    {
        SaveSettings();
        UpdateRichTextbox();
    }

    // Saves ALL field values in the form whenever the field changes. 
    // Warning: This function gets called each time a character is added to the 'Password' field.
    private void textBox2_TextChanged(object sender, EventArgs e)
    {
        SaveSettings();
        UpdateRichTextbox();
    }

UpdateRichTextbox() simply writes Name and Password to a rich text box in a formatted manner so that I can see their values: UpdateRichTextbox()只是以格式化方式将NamePassword写入富文本框,以便我可以看到它们的值:

    // Writes current values of each setting to Rich Textbox
    private void UpdateRichTextbox()
    {
        StringBuilder sb = new StringBuilder();
        sb.AppendLine($"Name: {Properties.Settings.Default.Name}");
        sb.AppendLine($"Password: {Properties.Settings.Default.Password}");
        richTextBox1.Text = sb.ToString();
    }

Attempt 尝试

I made sure to set the scope for both Name and Password setting in Project Settings to 'User'. 我确保将“项目设置”中的“ Name和“ Password设置的范围设置为“用户”。 I tried calling Properties.Settings.Default.Upgrade() after .Save(). 我尝试在.Save()之后调用Properties.Settings.Default.Upgrade ()。

Name and Password persisted when I moved the content of SaveSettings() to the callbacks invoked when those fields are changed: 当我将SaveSettings()的内容移动到更改这些字段时调用的回调时, NamePassword保持SaveSettings()

    // Saves ALL field values in the form whenever the field changes. 
    // Warning: This function gets called each time a character is added to the 'Name' field.
    private void textBox1_TextChanged(object sender, EventArgs e)
    {
        Properties.Settings.Default.Name = textBox1.Text;
        Properties.Settings.Default.Save();
        UpdateRichTextbox();
    }

    // Saves ALL field values in the form whenever the field changes. 
    // Warning: This function gets called each time a character is added to the 'Password' field.
    private void textBox2_TextChanged(object sender, EventArgs e)
    {
        Properties.Settings.Default.Password = textBox2.Text;
        Properties.Settings.Default.Save();
        UpdateRichTextbox();
    }

I'm not sure why my first approach didn't work. 我不确定为什么我的第一种方法不起作用。 How did the API devs intend for .Save() to be used? API开发人员是如何使用.Save()

Full Example 完整的例子

using System;
using System.Text;
using System.Windows.Forms;

namespace LoginForm
{
    public partial class Form1 : Form
    {
        // Called initially when the form application starts up
        public Form1()
        {
            InitializeComponent();
            LoadSettings();
        }

        // Load saved values to their respective field textboxes
        private void LoadSettings()
        {
            textBox1.Text = Properties.Settings.Default.Name;
            textBox2.Text = Properties.Settings.Default.Password;
        }

        // Writes current values of each setting to Rich Textbox
        private void UpdateRichTextbox()
        {
            StringBuilder sb = new StringBuilder();
            sb.AppendLine($"Name: {Properties.Settings.Default.Name}");
            sb.AppendLine($"Password: {Properties.Settings.Default.Password}");
            richTextBox1.Text = sb.ToString();
        }

        // Saves ALL field values in the form whenever the field changes. 
        // Warning: This function gets called each time a character is added to the 'Name' field.
        private void textBox1_TextChanged(object sender, EventArgs e)
        {
            Properties.Settings.Default.Name = textBox1.Text;
            Properties.Settings.Default.Save();
            UpdateRichTextbox();
        }

        // Saves ALL field values in the form whenever the field changes. 
        // Warning: This function gets called each time a character is added to the 'Password' field.
        private void textBox2_TextChanged(object sender, EventArgs e)
        {
            Properties.Settings.Default.Password = textBox2.Text;
            Properties.Settings.Default.Save();
            UpdateRichTextbox();
        }
    }
}

When the application restarts, Form1() calls LoadSettings() which, when executing textBox1.Text = Properties.Settings.Default.Name , modifies the textBox1.Text property causing the textBox1_TextChanged handler to run. 当应用程序重新启动时, Form1()调用LoadSettings() ,在执行textBox1.Text = Properties.Settings.Default.Name ,修改textBox1.Text属性,使textBox1_TextChanged处理程序运行。 That handler function calls SaveSettings() which then overwrites what had previously been stored in Properties.Settings.Default.Password using what's currently in the textBox2.Text field. 该处理函数调用SaveSettings() ,然后使用textBox2.Text字段中当前存储的内容覆盖之前存储在Properties.Settings.Default.Password中的内容。 Because the application had restarted, textBox2.Text is empty and thus the old value of Properties.Settings.Default.Password was overwritten with an empty string. 由于应用程序已重新启动,因此textBox2.Text为空,因此使用空字符串覆盖了Properties.Settings.Default.Password的旧值。

Thank you Jimi for helping me locate the user.config file and for his sage advice on what not to do in a textChanged event. 谢谢Jimi帮我找到了user.config文件,并提供了关于在textChanged事件中不该做什么的sage建议。 I can't see a good reason why you'd need to do something every time a character changes in your textBox either -- makes sense why most applications use an Apply or Save button. 我无法看到为什么每次textBox的角色发生变化时你都需要做某事 - 这就是大多数应用程序使用“ Apply或“ Save按钮的原因。 Seeing this file change as I step-debugged helped me identify the problem with my code. 我在步骤调试时看到这个文件发生了变化,这帮助我识别了我的代码问题。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM