Tuesday, January 20, 2009

Application.Settings, complex types, and you

So i came across the need to serialize some user settings between instances of an application. I happen to find the Application.Settings object and its "supposed" simple and straightforward uses.
With the Settings object you can add types at design time (or run time) in a key-value pair that load automatically with the application. and when set properly, you could also save values at runtime too. Best of all, the designer even allows you to add complex types. What luck!
...
...
or not...

Apparently while simple primitive types (int, string, colour) are supported, complex ones (youClass, PageSettings, PrinterSettings) arent... but the designer didnt get the memo. This may be an uninformed rant, but since i could find jack squat on the subject in my few days of research, i feel i can rant freely.

So yes, you can add complex types to the Application.Settings file. and yes, when you save you will see your super duper object all serialized in XML just the way you'd think it would be. But when you fire that bad boy up again and try to load that object, well... dont be surprised you get a null value instead.

to get around that, i did your simple serialize/deserialize manually. so what i needed was to save the user's printer settings after they saved them and wanted to keep them persistent between sessions.
with a little help from the following assemblies
using System.IO;
using System.Runtime.Serialization.Formatters.Binary;


we had the simple following:

private string str_page_settings = "page.set";
private string str_printer_settings = "printer.set";

internal void LoadSettings()
{
try
{
FileStream fs;
BinaryFormatter bf = new BinaryFormatter();

// load the PageSettings
if (File.Exists(str_page_settings))
{
fs = new FileStream(str_page_settings, FileMode.Open);
pageSetupDialog1.PageSettings = (PageSettings)bf.Deserialize(fs);

if (pageSetupDialog1.PageSettings == null)
{
pageSetupDialog1.PageSettings = new PageSettings();
}
}
else
pageSetupDialog1.PageSettings = new PageSettings();

// load the PrinterSettings
if (File.Exists(str_printer_settings))
{
fs = new FileStream(str_printer_settings, FileMode.Open);
printDialog1.PrinterSettings = (PrinterSettings)bf.Deserialize(fs);

if (printDialog1.PrinterSettings == null)
{
pageSetupDialog1.PrinterSettings = new PrinterSettings();
printDialog1.PrinterSettings = new PrinterSettings();
}
}
else
{
pageSetupDialog1.PrinterSettings = new PrinterSettings();
printDialog1.PrinterSettings = new PrinterSettings();
}
}
catch (Exception ex)
{
MessageBox.Show(ex.Message + " " + ex.StackTrace);
}
}


for loading, and for saving after the user saved:

private void btnPrint_Click(object sender, EventArgs e)
{
if (printDialog1.ShowDialog() == DialogResult.OK)
{
printDocument1.Print();
// serialize the printer settings the user chose
FileStream fs = new FileStream(str_printer_settings, FileMode.Create);
BinaryFormatter bf = new BinaryFormatter();
bf.Serialize(fs, printDialog1.PrinterSettings);
fs.Close();
}
}