Wednesday, September 23, 2009

C# Snippets: Saving User Preferences and Settings

Almost every application will at some stage need to store information, settings or user preferences to a file so that they can be retrieved at a later date. This has formerly be done using INI configuration files and more recently using the system Registry. This snippet will show you how to save settings in the Registry, to a SQL Database or to an XML file.

The first thing you need is a class that holds all the data you need to save, in this example we are creating a simple class called UserPreferences which contains two strings and an integer.

public class UserPreferences
{
private string _DisplayName;
public string DisplayName
{
get { return _DisplayName; }
set { _DisplayName = value; }
}

private string _Company;
public string Company
{
get { return _Company; }
set { _Company = value; }
}

private int _SomeValue;
public int SomeValue
{
get { return _SomeValue; }
set { _SomeValue = value; }
}
}

This class will form a basis for each of the derived classes that we will use for storing the information in XML, Registry and Database.

XML Serialization :

Attribute before the declaration or create a class that implements the ISerializable interface.


To save the user preferences class to an XML file simply create an XML Writer and invoke the Serialise method.


UserPreferences up = new UserPreferences();

XmlSerializer mySerializer = new XmlSerializer(typeof(UserPreferences));
StreamWriter myWriter = new StreamWriter("c:/prefs.xml");
mySerializer.Serialise(myWriter, up);
myWriter.Close();

To read the data back in, you simply call the Deserialise method.


UserPreferences up;

XmlSerializer mySerializer = new XmlSerializer(typeof(UserPreferences));
FileStream myFileStream = new FileStream("c:/prefs.xml",FileMode.Open);

up = (myTestClass)mySerializer.Deserialize(myFileStream);

You could also implement the IFormatter interface which will allow you to format the data and save it within a SOAP XML package using SoapFormatter or using a BinaryFormatter to store the data in a binary format.


Saving Settings within a SQL Database :

If you are developing an application that relies on data stored within a database (i.e. the program will not function without the database) then it makes sense to store configuration settings for the application within the database as well. This allows for a distributed model where the application can be downloaded to any client machine and settings retrieved from a central source.

We need to create an implementation of the class that will handle saving to the database. I am going to create a derived class which inherits the properties of UserPreferences as well as two new methods; one for saving to the database and one for loading the data back. Since we need to load the data each time the program is run (when we instantiate the UserPrefererences class) we can put the loading code into the constructor for the class.



public class SQLUserPreferences : UserPreferences
{
public SQLUserPreferences()
{
string connectionString = "Data Source=.\\SQLEXPRESS;AttachDbFilename=\"C:\\DOCUMENTS AND SETTINGS\\TROTTT\\MY DOCUMENTS\\VISUAL STUDIO 2005\\PROJECTS\\WINDOWSAPPLICATION5\\WINDOWSAPPLICATION5\\DATABASE1.MDF\";Integrated Security=True;Connect Timeout=30;User Instance=True";
SqlConnection sqlCon = new SqlConnection(connectionString);

sqlCon.Open();
string commandString = "SELECT * FROM appSettings WHERE UserLogon = '" +
System.Environment.UserDomainName + "\\" +
System.Environment.UserName.ToString() + "'";

SqlCommand sqlCmd = new SqlCommand(commandString, sqlCon);
SqlDataReader dr = sqlCmd.ExecuteReader();

while (dr.Read())
{
// Index 0 contains the domain/username used
// as a primary key for the database.
_DisplayName = dr.GetString(1);
_Company = dr.GetString(2);
_SomeValue = dr.GetInt32(3);
}

dr.Close();
sqlCon.Close();
}

public void Save()
{
string connectionString = "Data Source=localhost; Integrated Security=SSPI; Initial Catalog=appSettings";
SqlConnection sqlCon = new SqlConnection(connectionString);

sqlCon.Open();
string commandString = "UPDATE appSettings SET " +
"DisplayName = '" + _DisplayName + "', " +
"Company = '" + _Company + "', " +
"SomeValue = " + _SomeValue +
" WHERE UserLogon = '" +
System.Environment.UserDomainName + "//" +
System.Environment.UserName + "'";

SqlCommand sqlCmd = new SqlCommand(commandString, sqlCon);
sqlCmd.ExecuteNonQuery();
sqlCon.Close();
}
}


Saving Settings to the Registry :

The Windows registry is a general purpose mechanism for storing information that is to be maintained when a Windows application terminates. The .Net framework provides a class that provides easy access to registry methods. The registry contains many locations, called keys, such as HKEY_LOCAL_MACHINE and HKEY_CURRENT_USER. These are a few of the read only base keys that contain information about users, the operating system, the software installed and the settings for the current logged on user.

We are going to create a similar derived class to the one we created for SQL Databases; in fact the technique is exactly the same. You will need to add a reference to the namespace Microsoft.Win32.


public class RegUserPreferences : UserPreferences
{
public RegUserPreferences()
{
RegistryKey UserPrefs = Registry.CurrentUser.OpenSubKey("SOFTWARE\\Your-Company-Name\\App-Name", true);

if (UserPrefs != null)
{
_DisplayName = UserPrefs.GetValue("DisplayName");
_Company = UserPrefs.GetValue("Company");
_SomeValue = UserPrefs.GetValue("SomeValue");
}
else
{
// Key did not exist so use defaults
_DisplayName = System.Environment.UserName;
_CompanyName = System.Environment.UserDomainName;
_SomeValue = 0;
}
}

public void Save()
{
RegistryKey UserPrefs = Registry.CurrentUser.OpenSubKey("SOFTWARE\\Your-Company-Name\\App-Name", true);

if (UserPrefs == null)
{
// Value does not already exist so create it
RegistryKey newKey = Registry.CurrentUser.OpenSubKey("SOFTWARE\\Your-Company-Name", true);
UserPerfs = newKey.CreateSubKey("App-Name");
}

UserPerfs.SetValue("DisplayName", _DisplayName);
UserPerfs.SetValue("Company", _Company);
UserPerfs.SetValue("SomeValue", _SomeValue);
}
}


...

No comments:

Post a Comment

Followers