Saving settings in the language selection form
Someone recently sent me an error message from the language selection form, which uses Isolated Storage to save its settings. The file in which the settings are stored appeared to be locked by another process.
I have no idea why the file was locked, but my instinct is to throw out the isolated storage completely.
This code is at least 10 years old and back then isolated storage was recommended for saving user settings. I always thought it was too complicated, but I wanted to do it in a .NET way in the brave new .NET world.
It is now very easy to save user settings, if you add them via the project properties in Visual Studio. This is how you could change the code:
The following example is for C# in a WPF project, but it is more or less the same in VB and probably identical for a Windows Forms application.
Add two settings
- LanguageStartupMode, as an Integer with the default value 2. This value means that the dialog will be shown at program startup.
(Do not use the default value of 0, because this means that the form will not appear, even the first time that the program is started.) - SelectedLanguage as a string.
Change the LoadSettings() function
This code is in the file SelectLanguage.cs or SelectLanguage.xaml.cs.
Replace this old code
Old code | private void LoadSettings() { // Set the defaults StartupMode = enumStartupMode.ShowDialog; SelectedCulture = Thread.CurrentThread.CurrentUICulture; // Create an IsolatedStorageFile object and get the store // for this application. IsolatedStorageFile isoStorage = IsolatedStorageFile.GetUserStoreForDomain (); // Check whether the file exists if ( isoStorage.GetFileNames ( "CultureSettings.xml" ).Length > 0 ) //MLHIDE { // Create isoStorage StreamReader. StreamReader stmReader = new StreamReader ( new IsolatedStorageFileStream ( "CultureSettings.xml", FileMode.Open, isoStorage ) ); //MLHIDE XmlTextReader xmlReader = new XmlTextReader ( stmReader ); // Loop through the XML file until all Nodes have been read and processed. while ( xmlReader.Read () ) { switch ( xmlReader.Name ) { case "StartupMode": //MLHIDE StartupMode = (enumStartupMode)int.Parse ( xmlReader.ReadString () ); break; case "Culture": //MLHIDE string CultName = xmlReader.ReadString (); CultureInfo CultInfo = new CultureInfo ( CultName ); SelectedCulture = CultInfo; break; } } // Close the reader xmlReader.Close (); stmReader.Close (); } isoStorage.Close (); } |
New Code | private void LoadSettings() { // I don't think this should throw an exception int Mode = WpfApplication2.Properties.Settings.Default.LanguageStartupMode ; string CultName = WpfApplication2.Properties.Settings.Default.SelectedLanguage ; // Validate the enum if ( enumStartupMode.IsDefined ( typeof(enumStartupMode), Mode ) ) StartupMode = (enumStartupMode)Mode ; else StartupMode = enumStartupMode.ShowDialog ; // Validate the language with try/catch try { SelectedCulture = new CultureInfo ( CultName ) ; } catch ( System.Exception e ) { SelectedCulture = Thread.CurrentThread.CurrentUICulture; } } |
Replace WpfApplication2 with the namespace of your application.
Change the SaveSettings() function
Replace this old code
Old code | private void SaveSettings() { // Get an isolated store for user, domain, and assembly and put it into // an IsolatedStorageFile object. IsolatedStorageFile isoStorage = IsolatedStorageFile.GetUserStoreForDomain (); // Create isoStorage StreamWriter and assign it to an XmlTextWriter variable. IsolatedStorageFileStream stmWriter = new IsolatedStorageFileStream ( "CultureSettings.xml", FileMode.Create, isoStorage ); //MLHIDE XmlTextWriter writer = new XmlTextWriter ( stmWriter, Encoding.UTF8 ); writer.Formatting = Formatting.Indented; writer.WriteStartDocument (); writer.WriteStartElement ( "CultureSettings" ); //MLHIDE writer.WriteStartElement ( "StartupMode" ); //MLHIDE writer.WriteString ( ( (int)StartupMode ).ToString () ); writer.WriteEndElement (); writer.WriteStartElement ( "Culture" ); //MLHIDE writer.WriteString ( SelectedCulture.Name ); writer.WriteEndElement (); writer.WriteEndElement (); writer.Flush (); writer.Close (); stmWriter.Close (); isoStorage.Close (); } |
New Code | private void SaveSettings() { WpfApplication2.Properties.Settings.Default.LanguageStartupMode = (int)StartupMode ; WpfApplication2.Properties.Settings.Default.SelectedLanguage = SelectedCulture.Name ; WpfApplication2.Properties.Settings.Default.Save() ; } |
Replace WpfApplication2 with the namespace of your application.
I think you will agree that this code is simpler than the original version using isolated storage.
To be honest, I don't know whether there could still be a file access problem reading the settings. If there is, then it would be a problem in Microsoft's code.
At present, I have not changed the template file. I might do this in a future version, but first I will have to figure out how to add the user settings automatically.
Phil