Storing user settings with Data Standard

I just got a quite nice question on how to save user settings with Data Standard (formerly myView). Basically, the user don’t want to make the same selections over and over again. He’d like that the next time Data Standard shows up, the selection (especially for combo boxes) taken in the previous dialog will be represented. This makes sense, as probably you work for a while with the same or similar settings, such as project, customer, material, etc.

So the idea is to save the user selection in a little local text file. Of course we can think about saving this in something more “hidden” like registry or other places, but simple things should be kept simple. So we basically need 2 functions, one for reading the user settings and one for writing them. Here are the 2 functions:

function ReadUserSettings
{
  $global:userSettings = @{}
  if((Test-Path c:\temp\userSettings.txt) -eq $false) { New-Item c:\temp\userSettings.txt -ItemType file }
  Import-Csv c:\temp\userSettings.csv | ForEach-Object { $global:userSettings[$_.Key]=$_.Value }
}

function WriteUserSettings
{
  $global:userSettings.GetEnumerator() | Export-Csv c:\temp\userSettings.csv
}

Ok, these 2 functions are writing and reading the user settings from/into a hash-table (key value pair) into/from a CSV (Comma Separated Values) text file. Writing the hash-table into CSV is simple, while in order to read we have to run through all results and recreate the hash-table, that’s why the ForEach.

Place the 2 functions in your default.ps1 or create a new ps1 file like userSettings.ps1. either way, the 2 functions will be available at runtime. Now we can extend the InitializeWindow function. This is where we can do some preparations just before the dialog shows up. So we could easily set the values of those properties we like to pre-fill. Like this:

$Prop['Category'].Value = $global:userSettings['Category']

Basically, what we do here is setting the property Category to the value that comes from the CSV file. To be mentioned is the $global: prefix to our userSettings variable. This global implies that the following variable will be accessible everywhere (globally).

Additionally, we like to intercept the change of such a property and save it into the user settings. So when the user selects another value, we store it into our CSV and next time we reuse that value. In order to do that, we have to capture the PropertChanged Event for such a property, like this:

$Prop["Category"].add_PropertyChanged({
param( $parameter, $source)
if($source.PropertyName -eq "Value") {
Category_OnPropertyChanged }
})

The event handler now calls a function called Category_OnPropertyChanged. You can call this function as you like, it’s just a good convention to express the property name (in this case Category) and the action (OnPropertyChanged). Of course, we now need that function, which simply stored the selected value into the CSV.

And here’s a more complete overview of the code:

function ReadUserSettings
{
  $global:userSettings = @{}
  if((Test-Path c:\temp\userSettings.txt) -eq $false) { New-Item c:\temp\userSettings.txt -ItemType file }
  Import-Csv c:\temp\userSettings.txt | ForEach-Object { $global:userSettings[$_.Key]=$_.Value }
}

function WriteUserSettings
{
  $global:userSettings.GetEnumerator() | Export-Csv c:\temp\userSettings.txt
}

function InitializeWindow
{

#this is just an excerpt, so above you may have more/your code
  ReadUserSettings
  $Prop['Category'].Value = $global:userSettings['Category']
  $Prop["Category"].add_PropertyChanged({
param( $parameter, $source)
if($source.PropertyName -eq "Value") { Category_OnPropertyChanged }
                  })
}

function Category_OnPropertyChanged
{
  $global:userSettings['Category'] = $Prop['Category'].Value
WriteUserSettings
}

One last thing to remember: in this case we deal with combo-boxes. With combo-boxes, make sure that the SelectedValue attribute is set to your property. This attribute is responsible for reading and writing the binder property when the user selects a value, but also to set the selected value as the bomb-box shows up. So if your combo-box is empty as it shows up, then check if the SelectedValue is bound to your property, and of course the value set in the property must match with one of the combo-box options. Here’s a sample for a working combo-box:

<ComboBox ItemsSource="{Binding Prop[Category].ListValues}" SelectedValue="{Binding Prop[Category].Value}"  Grid.Row="0" Grid.Column="1" IsEnabled="{Binding IsNewEntryDialog}"/>

That’s it. I hope this helps!

This entry was posted in Data Standard, PowerShell. Bookmark the permalink.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s