Loading...
 
Multi-Language Add-In for Visual Studio

Multi-Language Add-In for Visual Studio


Saving settings in the language selection form

Germany

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.


Image

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.smile

Phil

Phil,

I do agree that Isolated Storage has issues, but with how we have chosen to implement our ML solutions, using the Project properties would cause me great issues as well I believe.

We have many "Child" apps that run, but we want them to run in the same Language as the "Parent App". In the parent app we set the Language and store it in a generic folder (Not Isolated Storage). In our Child apps (Which run on their own) we have modified the Lang Select screen to allow us to do a "Silent Look up" only of the file and change the Child app language accordingly.

If you switched to Project Properties we wouldn't be able to "Share" the setting across multiple applications would we?

Thanks