Solved

C# Code To Store Settings

Posted on 2011-03-25
11
566 Views
Last Modified: 2013-12-17
What would be some example code to store data for future use in a C# 2010 program? (ie: check boxes on a form left checked, or unchecked, and text that was left in a field, so when reponening the program, the text is still there) Thanks
0
Comment
Question by:NewMacAdmin
[X]
Welcome to Experts Exchange

Add your voice to the tech community where 5M+ people just like you are talking about what matters.

  • Help others & share knowledge
  • Earn cash & points
  • Learn & ask questions
11 Comments
 
LVL 2

Accepted Solution

by:
ericpeckham earned 400 total points
ID: 35218256
For example, add a checkbox to a form, as follows:

 The checkbox on the form
You can bind its value to a value saved in a user settings file, as in the following image.  I created the saved value "SaveMe" by clicking on "New..." at the bottom of the drop-down window:

 checkBox1 properties
Then all you have to do is make sure you save the settings, as in this example, when the main window is being closed:

namespace WindowsFormsApplication1
{
      public partial class Form1 : Form
      {
            public Form1()
            {
                  InitializeComponent();
            }

            private void Form1_FormClosing(object sender, FormClosingEventArgs e)
            {
                  WindowsFormsApplication1.Properties.Settings.Default.Save();
            }
      }
}
0
 

Author Comment

by:NewMacAdmin
ID: 35218266
Where will that settings file be placed, what will it's name/file extension be?  Can I encrypt it to prevent the data from being tampered with?
0
 
LVL 2

Expert Comment

by:ericpeckham
ID: 35218291
I assumed you were using Visual Studio with a WinForms application.  Here's the code that the designer generated for the checkbox (from Form1.Designer.cs):

                  // checkBox1
                  //
                  this.checkBox1.AutoSize = true;
                  this.checkBox1.Checked = global::WindowsFormsApplication1.Properties.Settings.Default.SaveMeValue;
                  this.checkBox1.DataBindings.Add(new System.Windows.Forms.Binding("Checked", global::WindowsFormsApplication1.Properties.Settings.Default, "SaveMeValue", true, System.Windows.Forms.DataSourceUpdateMode.OnPropertyChanged));
                  this.checkBox1.Location = new System.Drawing.Point(27, 24);
                  this.checkBox1.Name = "checkBox1";
                  this.checkBox1.Size = new System.Drawing.Size(69, 17);
                  this.checkBox1.TabIndex = 1;
                  this.checkBox1.Text = "Save Me";
                  this.checkBox1.UseVisualStyleBackColor = true;

Here's the code VS generated for the setting to be saved (from Properties\Settings.Designer.cs):

namespace WindowsFormsApplication1.Properties {
   
   
    [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
    [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.VisualStudio.Editors.SettingsDesigner.SettingsSingleFileGenerator", "10.0.0.0")]
    internal sealed partial class Settings : global::System.Configuration.ApplicationSettingsBase {
       
        private static Settings defaultInstance = ((Settings)(global::System.Configuration.ApplicationSettingsBase.Synchronized(new Settings())));
       
        public static Settings Default {
            get {
                return defaultInstance;
            }
        }
       
        [global::System.Configuration.UserScopedSettingAttribute()]
        [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
        [global::System.Configuration.DefaultSettingValueAttribute("False")]
        public bool SaveMeValue {
            get {
                return ((bool)(this["SaveMeValue"]));
            }
            set {
                this["SaveMeValue"] = value;
            }
        }
    }
}

0
Forrester Webinar: xMatters Delivers 261% ROI

Guest speaker Dean Davison, Forrester Principal Consultant, explains how a Fortune 500 communication company using xMatters found these results: Achieved a 261% ROI, Experienced $753,280 in net present value benefits over 3 years and Reduced MTTR by 91% for tier 1 incidents.

 

Author Comment

by:NewMacAdmin
ID: 35218305
It doesn't seem to five much option for encrypting the settings file.  Is there a manual way to save settings such as text in a txtbox or a checkbox check status?
0
 
LVL 2

Expert Comment

by:ericpeckham
ID: 35218428
Here's a brief description of how user settings files work.

When VS builds the app, it places a file containing default application settings in the same directory as the application - in this case the file is named WindowsFormsApplication1.exe.config.

When the settings are first saved (in this case the first time the window is closed), .NET creates a file under the user's AppData directory, which looks a lot like the .config file above, except it has the actual saved settings instead of the default settings.  On my computer, it was saved at C:\Users\eric\AppData\Local\Microsoft\WindowsFormsApplication1._Url_31h2hba23faolvxzzag45mwubsv0qqk3\1.0.0.0\user.config.  If this file exists when the application first looks for a value, it will look to see if this file exists, and if so, it loads those settings.  If it's not there, it uses the default settings in the app directory.

I think there may be a way to encrypt this data, although you normally shouldn't need to worry about that as the user area of a hard drive is usually off limits to other users.  If you need to encrypt sensitive data, you will need to do that in your code before it's saved, and then decrypt it when it is being loaded.
0
 

Author Comment

by:NewMacAdmin
ID: 35218444
How can I do that in my code then?  Some of the data will be sensitive. Thanks
0
 
LVL 7

Expert Comment

by:nbove
ID: 35218819
If you are storing sensitive data, you should probably be using a database like SQL Server or Oracle.
0
 
LVL 2

Expert Comment

by:ericpeckham
ID: 35218884
nbove makes a good point.  We could probably be more helpful if you were to explain exactly what you need to do.  I would appreciate it if you would accept my answer, as I have answered your original question.  This encryption thing should probably be another question, and I would be glad to help with that.
0
 
LVL 2

Assisted Solution

by:_valkyrie_
_valkyrie_ earned 100 total points
ID: 35219705
You could use a collection of settings, serialize it and encrypt it during that process.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Security.Cryptography;
using System.IO;
using System.Runtime.Serialization.Formatters.Binary;
using System.Runtime.Serialization;

namespace WpfApplication1
{
    [Serializable()]
    public class Settings : Dictionary<string,string>
    {
        private const string Salt = "911BE5F6-B97B-4156-99F5-DC70DB585B33";

        public Settings() { }

        public Settings(SerializationInfo info, StreamingContext context) : base(info, context) { }
            
        #region " Class Storage "
        public static void Save(Settings settings, string filename, string password)
        {
            RijndaelManaged algorithm = Settings.SetupEncryptionAlgorithm(password);

            using (FileStream output = new FileStream(filename, FileMode.Create))
            {
                using (CryptoStream encryptedStream = 
                    new CryptoStream(output, algorithm.CreateEncryptor(), CryptoStreamMode.Write))
                {
                    BinaryFormatter serializer = new BinaryFormatter();
                    serializer.Serialize(encryptedStream, settings);
                }
            }
        }

        public static Settings Load(string filename, string password)
        {
            if (!File.Exists(filename))
                return new Settings();
            Settings toReturn;

            RijndaelManaged algorithm = Settings.SetupEncryptionAlgorithm(password);

            using (FileStream input = new FileStream(filename, FileMode.Open))
            {
                using (CryptoStream decryptedStream = 
                    new CryptoStream(input, algorithm.CreateDecryptor(), CryptoStreamMode.Read))
                {
                    BinaryFormatter serializer = new BinaryFormatter();
                    toReturn = (Settings)serializer.Deserialize(decryptedStream);
                }
            }

            return toReturn;
        }

        private static RijndaelManaged SetupEncryptionAlgorithm(string password)
        {
            RijndaelManaged algorithm = new RijndaelManaged();
            Rfc2898DeriveBytes key =
                new Rfc2898DeriveBytes(password, Encoding.ASCII.GetBytes(Settings.Salt));
            algorithm.Key = key.GetBytes(algorithm.KeySize / 8);
            algorithm.IV = key.GetBytes(algorithm.BlockSize / 8);
            return algorithm;
        }
        #endregion

    }
}

Open in new window


I attached the full example project which includes a UI that saves 1 string from a textbox. The password is hard-coded (terrible idea but just for a quick example).


Ok, it won't let me attach the zip file. So here is the WPF Window code:
<Window x:Class="WpfApplication1.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        Title="MainWindow" SizeToContent="Height" Width="525" Closing="Window_Closing">
    <Grid>
        <Grid.ColumnDefinitions>
            <ColumnDefinition Width="*" />
            <ColumnDefinition Width="Auto" />
        </Grid.ColumnDefinitions>
        <Grid.RowDefinitions>
            <RowDefinition Height="Auto" />
            <RowDefinition Height="*" />
        </Grid.RowDefinitions>
        <TextBox Name="txtData" Grid.ColumnSpan="2" Margin="5" />
        <Button Content="Save" HorizontalAlignment="Right" Name="btnSave" Grid.Row="1"  Margin="0,0,5,5" IsDefault="True" Grid.Column="0" Click="btnSave_Click" />
        <Button Content="Load" HorizontalAlignment="Right" Name="btnLoad" Grid.Row="1"  Margin="0,0,5,5" Grid.Column="1" Click="btnLoad_Click" />
    </Grid>
</Window>

Open in new window

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;

namespace WpfApplication1
{
    /// <summary>
    /// Interaction logic for MainWindow.xaml
    /// </summary>
    public partial class MainWindow : Window
    {
        private Settings settings;
        private const string MyFirstKey = "MyFirstSetting";

        public MainWindow()
        {
            InitializeComponent();
            this.settings = Settings.Load("test.cfg", "MyPassword");
            if (this.settings.ContainsKey(MyFirstKey))
                this.txtData.Text = this.settings[MyFirstKey];
        }

        private void btnSave_Click(object sender, RoutedEventArgs e)
        {
            if (this.settings.ContainsKey(MyFirstKey))
                this.settings[MyFirstKey] = this.txtData.Text;
            else
                this.settings.Add(MyFirstKey, this.txtData.Text);
        }

        private void btnLoad_Click(object sender, RoutedEventArgs e)
        {
            if (this.settings.ContainsKey(MyFirstKey))
                this.txtData.Text = this.settings[MyFirstKey];
        }

        private void Window_Closing(object sender, System.ComponentModel.CancelEventArgs e)
        {
            Settings.Save(this.settings, "test.cfg", "MyPassword");
        }
    }
}

Open in new window

0
 
LVL 70

Expert Comment

by:Éric Moreau
ID: 35221847
0
 

Author Comment

by:NewMacAdmin
ID: 35222174
I am simply storing a checkbox to determine if a string should be saved.  The string is a seed to generate a unique password for a machine (from a previously asked question of mine).  The encryption is just to protect the seed.

ericpeckham is correct in that he did answer my original question.  I will however award a few points for the answer to my follow up question. Thanks
0

Featured Post

PeopleSoft Has Never Been Easier

PeopleSoft Adoption Made Smooth & Simple!

On-The-Job Training Is made Intuitive & Easy With WalkMe's On-Screen Guidance Tool.  Claim Your Free WalkMe Account Now

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

Update (December 2011): Since this article was published, the things have changed for good for Android native developers. The Sequoyah Project (http://www.eclipse.org/sequoyah/) automates most of the tasks discussed in this article. You can even fin…
This article is for Object-Oriented Programming (OOP) beginners. An Interface contains declarations of events, indexers, methods and/or properties. Any class which implements the Interface should provide the concrete implementation for each Inter…
The viewer will learn how to use NetBeans IDE 8.0 for Windows to connect to a MySQL database. Open Services Panel: Create a new connection using New Connection Wizard: Create a test database called eetutorial: Create a new test tabel called ee…
The viewer will learn how to synchronize PHP projects with a remote server in NetBeans IDE 8.0 for Windows.

739 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question