Click here to Skip to main content
Click here to Skip to main content

User Settings Applied

By , 20 Apr 2012
 

User Settings Applied

Introduction

Although just one among many requirements, the capability of a software to remember user input and reuse that information upon recurring operations is a criterion of quality which directly influences user experience. In the wild, however, practice shows that user settings are insufficiently supported: Why can't that software remember this?

Analyzing the reasons for that, the following items come to mind:

  • Integration of a user setting is too tedious
  • Existing tools offer limited support to manage user settings
  • User settings cannot be integrated dynamically
  • Migration of user settings upon program updates is not well defined

This article describes a component that shows how to easily implement user settings. The following goals were driving its development:

  • Simple integration of a user setting: optimally, just a single statement per setting
  • The component should be capable of supporting Console-, WinForms- and WPF-applications
  • Compatibility to the .NET 2+ configuration must be ensured
  • Standard components should support recurring needs, such as, for example, location and size of a window, or grid column layout
  • XAML driven user settings
  • Tracking settings changes
  • Collecting settings dynamically
  • Automatic migration of user settings with new program versions
  • Automatic generation of multiple, context-dependent, configuration sections
  • Bind settings to class properties using attributes

The following sample shows a simple usage of this component:

// ------------------------------------------------------------------------
class MyApplication
{
  // ----------------------------------------------------------------------
  public MyApplication()
  {
    settings = new ApplicationSettings( this ); // register class settings
  } // MyApplication

  // ----------------------------------------------------------------------
  [PropertySetting] // register setting using an attribute
  public int MyValue { get; set; }

  // ----------------------------------------------------------------------
  public void Execute()
  {
    settings.Load(); // load settings considering previous versions
    ...
    settings.Save(); // save settings to custom configuration section
  } // Load

  // ----------------------------------------------------------------------
  // members
  private readonly ApplicationSettings settings;

} // class MyApplication

Introduction to the .NET Configuration

Since CLR 2.0, the .NET Framework offers an extensive configuration module in System.Configuration. It differentiates between program and user settings:

Type File Location Occurrence Usage/Administration
Application app.config Program Folder 1 per installation Visual Studio Project Properties: Settings
User user.config User Profile Folder 1 per user Derivation of ApplicationSettingsBase

The usage scenario determines which type of setting to choose:

Criterion/Requirement Application Setting User Setting
Setting is the same for all users (e.g., database connection) x
Setting can vary per user (e.g., theme) x
Temporary/local setting (e.g., location and size of a window) x
Storage of user input or selection (e.g., text alignment) x
Necessity to store settings fine grained (e.g., per plug-in) x

The matrix shows that the usage of user settings is preferable in many scenarios!

Control over the user settings is gained through inheriting from the class ApplicationSettingsBase. A single setting value can be defined via a property and a property attribute. The methods Reload(), Reset(), Save(), and Upgrade() determine the runtime behavior. The following illustration shows the data flow of the .NET user configuration:

User Settings Data Flow

The 'Default Value' is defined through the property attribute DefaultSettingValueAttribute. The value 'Init Value' is controlled by the .NET Framework. Access to the value of 'Session Value' occurs through the property which is marked with the UserScopedSettingAttribute, which in turn uses ApplicationSettingsBase.Item.

The methods Reload() and Reset() support freshly loading all settings and setting them back to their 'Default Values, respectively.

When performing the first Save(), all user settings get stored in the XML file user.config. With every following program launch, the .NET Framework automatically loads them again (action Start). Where that configuration file will be located is influenced by several factors:

  • Profile Directory: The local or roaming profile directory (e.g., C:\Documents and Settings\MyName)
  • Company Name: The value of the AssemblyCompanyAttribute in AssemblyInfo.cs
  • App Name: The value of the AssemblyProductAttribute in AssemlyInfo.cs
  • Evidence Type and Evidence Hash: Information derived from the app domain evidence
  • Version: The value of the AssemblyVersionAttribute in AssemblyInfo.cs

If any of these factors change, the user settings will be stored (and looked for) in a different folder. The method Upgrade() offers some support for migrating user settings from previous versions. Care should be taken, however, when changing either the company or the application name, as these changes will prevent future upgrades.

The .NET user settings configuration is capable of storing the values of several ApplicationSettingsBases in the same file. The SettingsKey acts as a grouping mechanism to separate them in the XML file:

<?xml version="1.0" encoding="utf-8"?>
<configuration>
  <configSections>
    <sectionGroup name="userSettings" type="System.Configuration.UserSettingsGroup,
      System, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" >
      <section name="Itenso.Configuration.WindowSettings.MySettings1"
        type="System.Configuration.ClientSettingsSection, System,
        Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089"
        allowExeDefinition="MachineToLocalUser" requirePermission="false" />
      <section name="Itenso.Configuration.WindowSettings.MySettings2"
        type="System.Configuration.ClientSettingsSection, System,
        Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089"
        allowExeDefinition="MachineToLocalUser" requirePermission="false" />
    </sectionGroup>
  </configSections>
  <userSettings>
    <Itenso.Configuration.WindowSettings.MySettings1>
      <setting name="MySetting1" serializeAs="String">
        <value>Value1</value>
      </setting>
    </Itenso.Configuration.WindowSettings.MySettings1>
    <Itenso.Configuration.WindowSettings.MySettings2>
      <setting name="MySetting2" serializeAs="String">
        <value>Value2</value>
      </setting>
    </Itenso.Configuration.WindowSettings.MySettings2>
  </userSettings>
</configuration>

The Client Settings FAQ offers a lot more interesting insights about the .NET configuration. The article Read/Write App.Config File with .NET 2.0 demonstrates the management of application settings.

Extended .NET User Settings

To achieve the desired improvements, a user setting has been separated from ApplicationSettingsBase. The new element Setting binds a setting value to a definable source. The following Setting classes are available:

Class Technology Function
Setting Console, WinForms, WPF Save/load, and integration to the System.Configuration user settings
ValueSetting Console, WinForms, WPF Setting value without binding
FieldSetting Console, WinForms, WPF Binding to a class field
PropertySetting Console, WinForms, WPF Binding to a class property
DataGridViewSetting WinForms DataGridView column settings
DependencyPropertySetting WPF Binding to a dependency property
ListViewSetting WPF ListView column settings

The class Setting acts as the base class of all settings. The class ValueSettingBase takes the role of simple value based settings.

The following illustration shows how these extended user settings influence the data flow:

User Settings Extended Data Flow

Load() transfers the user settings into a Setting. Through the integration of the upgrade functionality into Load(), we have achieved the automatic upgrade of user settings. The actions Reload() and Reset() synchronize the 'Setting Value' with the 'Session Value'. Save() uses the 'Setting Value' as its source. Settings with a binding such as PropertyBinding will use the class property value.

The property Setting.HasChanged indicates whether the 'setting value' has changed with respect to the 'Session Value'. This can be used to confirm the saving of settings.

For automating the runtime behavior, various derivations of ApplicationSettingsBase are available:

Class Technology Function
ApplicationSettings Console, WinForms, WPF Settings management, Save/Load, Auto-Upgrade
ControlSettings WinForms Load/Save for a Control
FormSettings WinForms Load/Save for a Form with Location/Size/WindowState
WindowApplicationSettings WPF Load/Save for an Application
FrameworkElementSettings WPF Load/Save for a FrameworkElement
WindowSettings WPF Load/Save for a Window with Location/Size/WindowState

The class ApplicationSettings is the base class for all settings.

The SettingCollector element allows to dynamically merge settings. The following SettingCollector classes are available:

Class Technology Function
PropertySettingCollector WinForms, WPF Binding to a child class property
DependencyPropertySettingCollector WPF Binding to a child class dependency property

A SettingCollector iterates over the UI element hierarchy, and registers a property setting with all instances of a class. Applying the PropertySettingCollector, for example, on CheckBox.IsChecked will store the state of all checkboxes in the user settings. The event SettingCollector.CollectingSetting allows to control the registering of each setting individually. For performance reasons, a SettingCollector should not combine more than 10 settings.

Using the Code

Console Application

Support for user settings is achieved through the class ApplicationSettings:

// ------------------------------------------------------------------------
class Program
{
  // ----------------------------------------------------------------------
  [PropertySetting( DefaultValue=-1 )]
  public int StatusCode { get; set; }

  // ----------------------------------------------------------------------
  public void Execute()
  {
    ApplicationSettings applicationSettings = new ApplicationSettings( this );
    applicationSettings.Load();

    Console.Write( "Please enter a number: " );
    statusCode = int.Parse( Console.ReadLine() ); // modifying the field value

    applicationSettings.Save();
  } // Execute

  // ----------------------------------------------------------------------
  static void Main()
  {
    new Program().Execute();
  } // Main

} // class Program

Entering the value 22 leads to the following user configuration:

<?xml version="1.0" encoding="utf-8"?>
  <configuration>
    <configSections>
      <sectionGroup name="userSettings">
        <section name="Itenso.Configuration.ApplicationSettings.Program"
          type="System.Configuration.ClientSettingsSection, System,
          Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089"
          allowExeDefinition="MachineToLocalUser" requirePermission="false" />
      </sectionGroup>
    </configSections>
    <userSettings>
      <Itenso.Configuration.ApplicationSettings.Program>
        <setting name="StatusCode" serializeAs="String">
          <value>22</value>
        </setting>
        <setting name="UpgradeSettings" serializeAs="String">
          <value>False</value>
        </setting>
      </Itenso.Configuration.ApplicationSettings.Program>
    </userSettings>
  </configuration>

The meaning of the value UpgradeSettings will be shown later on.

WinForms Application

The following example shows how to implement custom application or form settings:

Windows Forms User Settings Sample

Control Settings

Handling the user settings of Control and its derivations is supported by the class ControlSettings:

// ------------------------------------------------------------------------
public class MyListBox : ListBox
{
  // ----------------------------------------------------------------------
  public MyListBox()
  {
    if ( DesignMode )
    {
      return;
    }
    ControlSettings controlSettings = new ControlSettings( this );
    controlSettings.Settings.Add(
      new PropertySetting(     // bind setting to the property
        this,                  // source component
        "SelectedIndex" ) );   // property name
  } // MyListBox

} // class MyListBox

Form Settings

User settings of a Windows Form and its derivations are controlled by the class FormSettings:

// ------------------------------------------------------------------------
public partial class MyForm : Form
{
  // ----------------------------------------------------------------------
  public MyForm()
  {
    InitializeComponent();
    FormSettings formSettings = new FormSettings( this );
  } // MyForm
} // class MyForm

FormSettings automatically stores the location, size, and the state of a window. Several switches such as FormSettings.UseLocation allow you to customize the automatic behavior. Of special interest is the switch FormSettings.AllowMinimized (default=false) which controls the storage behavior for Windows in the minimized state.

DataGridView Settings

Position (order) and width of DataGridView columns can be stored in the user settings using the class DataGridViewSetting:

// ------------------------------------------------------------------------
public partial class MyForm : Form
{
  // ----------------------------------------------------------------------
  public MyForm()
  {
    InitializeComponent();
    FormSettings formSettings = new FormSettings( this );
    formSettings.Settings.Add( new DataGridViewSetting( myDataGridView ) );
  } // MyForm

} // class MyForm

The example DataGridView also contains a demonstration of a save confirmation.

Collected Settings

The following example shows how to store all the CheckBox state values of a Form:

// ------------------------------------------------------------------------
public partial class MyForm : Form
{
  // ----------------------------------------------------------------------
  public MyForm()
  {
    InitializeComponent();
    FormSettings formSettings = new FormSettings( this );
    formSettings.CollectingSetting +=
      new SettingCollectorCancelEventHandler( FormSettingsCollectingSetting );
    formSettings.SettingCollectors.Add( new PropertySettingCollector
        ( this, typeof( CheckBox ), "Checked" ) );
  } // MyForm

  // ----------------------------------------------------------------------
  private void FormSettingsCollectingSetting
    ( object sender, SettingCollectorCancelEventArgs e )
  {
    if ( e.Element == this.myCheckBox ) // exclude this checkbox
    {
       e.Cancel = true;
    }
  } // FormSettingsCollectingSetting
} // class MyForm

WPF - Code Behind

The accompanying example shows how to implement custom application or window settings:

WPF Window Settings Sample

DerivedSettingsWindow.xaml uses BaseWindow to demonstrate how a Window inheritance hierarchy can be built. By including the WindowSettings in the base class BaseWindow, all the derivations and XAML instances will automatically store the location, size, and state.

FrameworkElement Settings

Handling user settings of FrameworkElement and its derivations is supported by the class FrameworkElementSettings:

// ------------------------------------------------------------------------
public class MyListBox : ListBox
{
  // ----------------------------------------------------------------------
  public MyListBox()
  {
    if ( DesignerProperties.GetIsInDesignMode( this ) )
    {
      return;
    }
    FrameworkElementSettings listBoxSettings = new FrameworkElementSettings( this );
    listBoxSettings.Settings.Add(
      new DependencyPropertySetting(  // bind setting to the dependency-property
        this,                         // source component
        SelectedIndexProperty ) );    // dependency-property name
  } // MyListBox
} // class MyListBox

In contrast to the WinForm variant, WPF offers an elegant way to bind a Setting to a property with the DependencyProperty. Invalid bindings will be recognized at compile time.

Window Settings

The settings of a Window and its derivations is controlled by the class WindowSettings:

// ------------------------------------------------------------------------
public partial class MyWindow : Window
{
  // ----------------------------------------------------------------------
  public MyWindow()
  {
    WindowSettings windowSettings = new WindowSettings( this );
  } // MyWindow

} // class MyWindow

WindowSettings automatically stores location, size, and state of a window. The switches FormSettings.UseLocation, FormSettings.AllowMinimized, and so on control the saving behavior (see above).

ListView Settings

Position (order) and width of ListView columns can be stored in the user settings using the class ListViewSetting:

// ------------------------------------------------------------------------
public partial class MyWindow : Window
{
  // ----------------------------------------------------------------------
  public MyWindow()
  {
    WindowSettings windowSettings = new WindowSettings( this );
    windowSettings.Settings.Add( new ListViewSetting( myListView ) );
  } // MyWindow

} // class MyWindow

The example ListView also contains a demonstration of a save confirmation. The article ListView Layout Manager demonstrates how to restrict column widths of ListViews and how to support proportional column widths.

Collected Settings

The following example shows how to store all the CheckBox state values of a Window:

// ------------------------------------------------------------------------
public partial class MyWindow : Window
{
  // ----------------------------------------------------------------------
  public MyWindow()
  {
    WindowSettings windowSettings = new WindowSettings( this );
    windowSettings.CollectingSetting +=
      new SettingCollectorCancelEventHandler( WindowSettingsCollectingSetting );
    windowSettings.SettingCollectors.Add( new DependencyPropertySettingCollector
      ( this, CheckBox.IsCheckedProperty ) );
  } // MyWindow

  // ----------------------------------------------------------------------
  private void WindowSettingsCollectingSetting
      ( object sender, SettingCollectorCancelEventArgs e )
  {
    if ( e.Element == this.myCheckBox ) // exclude this checkbox
    {
      e.Cancel = true;
    }
  } // WindowSettingsCollectingSetting
} // class MyWindow

WPF - XAML

User settings can be declared in XAML as follows:

<Window
  x:Class="Itenso.Solutions.Community.ConfigurationWindowsDemo.XamlUserSettingsWindow"
  xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
  xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
  xmlns:config="clr-namespace:Itenso.Configuration;
    assembly=Itenso.Configuration.Windows"
  config:WindowSettings.Settings="XamlWindowSettings">
  <StackPanel>

    <CheckBox
      x:Name="MyOption"
      Content="My Option"

      config:DependencyPropertySetting.Property=
        "{x:Static CheckBox.IsCheckedProperty}" />
  </StackPanel>
</Window>

The attribute config:WindowSettings.Settings assigns the WindowSetting to the window. Storage of the Window's location/size/state happens automatically. Upon upgrading, the values of the previous version will be migrated automatically, too.

The attribute config:DependencyPropertySetting.Property leads to the treating of CheckBox.IsChecked as a user setting and hence its storage.

Important: For the property value to be stored, the element has to have a value in its x:Name.

The example above leads to the following configuration data:

<Itenso.Configuration.WindowSettings.XamlWindowSettings>
  <setting name="Window.Top" serializeAs="String">
    <value>203</value>
  </setting>
  <setting name="Window.Height" serializeAs="String">
    <value>200</value>
  </setting>
  <setting name="Window.Left" serializeAs="String">
    <value>813</value>
  </setting>
  <setting name="Window.Width" serializeAs="String">
    <value>713</value>
  </setting>
  <setting name="Window.WindowState" serializeAs="String">
    <value>Normal</value>
  </setting>
  <setting name="UpgradeSettings" serializeAs="String">
    <value>False</value>
  </setting>
  <setting name="MyOption.IsChecked" serializeAs="String">
    <value>True</value>
  </setting>
</Itenso.Configuration.WindowSettings.XamlWindowSettings>

ListView Settings

Using XAML, the position (order) and width of ListView columns can be stored in the user settings as follows:

<Window
  x:Class="Itenso.Solutions.Community.ConfigurationWindowsDemo.XamlUserSettingsWindow"
  xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
  xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
  xmlns:config="clr-namespace:Itenso.Configuration;
          assembly=Itenso.Configuration.Windows"
  DataContext="{Binding RelativeSource={RelativeSource Self}}"
  config:WindowSettings.Settings="XamlWindowSettings">
  <StackPanel>
    <ListView
      Name="MyListView"
      ItemsSource="{Binding MyList}"
      config:ListViewSetting.Settings="MyListView">
      ...
    </ListView>
  </StackPanel>
</Window>

The attribute config:ListViewSetting.Settings defines the name of the setting. The assignment of config:WindowSettings.Settings to the Window is necessary.

Collected Settings

The following example shows the usage of a SettingCollector in XAML:

<Window
  x:Class="Itenso.Solutions.Community.ConfigurationWindowsDemo.XamlUserSettingsWindow"
  xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
  xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
  xmlns:config="clr-namespace:Itenso.Configuration;
    assembly=Itenso.Configuration.Windows"
  DataContext="{Binding RelativeSource={RelativeSource Self}}"
  config:WindowSettings.Settings="XamlWindowSettings"
  config:WindowSettings.CollectedSetting="{x:Static CheckBox.IsCheckedProperty}">
  <StackPanel>
    <CheckBox
      x:Name="MyOption"
      Content="My Option"
      config:WindowSettings.ExcludeElement="True" />
  </StackPanel>
</Window>

The config:WindowSettings.CollectedSetting registers a DependencyPropertySetting. This only considers elements which contain a defined x:Name. Using config:WindowSettings.ExcludeElement allows to exclude an element from registration.

Points of Interest

  • The sample applications demonstrate how to implement a 'Save as Default' feature per Form/Window
  • Specifying an invalid name for a FieldSetting or a PropertySetting will result in an exception
  • readonly fields for a FieldSetting will lead to an exception
  • PropertySetting: an assigned property without get; set; accessors will lead to an exception
  • The setting UpgradeSettings has a default value of true and will be set to false after an upgrade
  • A Setting provides runtime control via the events ValueSaving and ValueLoading
  • ApplicationSettings.UseAutoUpgrade controls the auto-upgrade behaviour
  • The ApplicationSettings uses a LocalFileSettingsProvider
  • The Setting serialization format can be specified with the property ValueSettingBase.SerializeAs. Examples of how to serialize settings in a binary format can be found in DataGridViewSetting and ListViewSetting
  • The store behavior can be influenced with the FormSettings.SaveCondition and WindowSettings.SaveCondition properties, so it honors the DialogResult
  • The method Setting.CreateSettingProperty() demonstrates how to dynamically include a SettingsProperty
  • WindowSettings.OnWindowSettingsChanged and DependencyPropertySetting.FindApplicationSettings demonstrate how a property (DependencyPropertySetting.ApplicationSettingsProperty) can dynamically be assigned to an object and evaluated. The very case uses the property to determine which ApplicationSettings should be assigned a DependencyPropertySetting
  • The DepedencyPropertySetting will be assigned to the first ApplicationSettings which is found in the parent hierarchy. This can then either be a WindowSettings or a FrameworkElementSettings

History

  • 12th April, 2012 - v1.1.0.0
    • Fixed minor issues
    • ReSharped source code
    • Enhanced WPF example
    • Fixed article formatting
  • 15th February, 2011
    • Enhanced support for maximized window in multi-monitor environment - thanks Ryan
    • Added projects and solutions for Visual Studio 2010
    • Refactored code - or rather 'ReSharped'
  • 18th March, 2009
    • ApplicationSettings: Added new events SettingSaving and SettingLoading
    • SettingValueEventArgs and SettingValueCancelEventArgs: New property TargetValue which allows to change the setting value within the save/load events
    • FormSettings and WindowSettings: Made all settings public available
  • 15th January, 2009
    • Added FieldSettingAttribute and PropertySettingAttribute
    • Refactored component to use automatic properties
    • Added sample with attribute settings
  • 20th May, 2008
    • Collecting settings: new classes PropertySettingCollector and DependencyPropertySettingCollector
    • Tracking setting changes: new properties Setting.HasChanged and SettingCollection.HasChanges
    • WinForms: save settings depending on Form.DialogResult, new property FormSettings.SaveCondition
    • WPF: save settings depending on Window.DialogResult, new property WindowSettings.SaveCondition
    • Error handling: new properties Setting.ThrowOnErrorSaving and Setting.ThrowOnErrorLoading
  • 10th May, 2008
    • WinForms: new setting DataGridViewSetting
    • WPF: new setting ListViewSetting
    • WinForms sample application: new samples for color and font settings
    • WPF sample application: new sample for a color setting based on a custom dependency property
    • Added link to article Read/Write App.Config File with .NET 2.0
    • Added link to article ListView Layout Manager
  • 3rd May, 2008
    • Initial public release

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)

About the Author

Jani Giannoudis
Software Developer (Senior)
Switzerland Switzerland
Member
Jani is Co-founder of Meerazo.com, a free service which allows to share resources like locations, things, persons and their services in a cooperating group of people.

Sign Up to vote   Poor Excellent
Add a reason or comment to your vote: x
Votes of 3 or less require a comment

Comments and Discussions

 
You must Sign In to use this message board.
Search this forum  
    Spacing  Noise  Layout  Per page   
QuestionListView in UserControlmemberMember 954015519 Apr '13 - 14:40 
Hi, I'm trying to save and load the settings for a WPF ListView. I'm having some difficulty because my ListView isn't in a "Window" it's in a UserControl. Is it possible to Save or Load my ListView using your app? This is how I'm saving my ListView:
_listViewSetting = new ListViewSetting(myListView);
_listViewSetting.ApplicationSettings = new ApplicationSettings(this);
_listViewSetting.Save();
 
Thanks and great article!
AnswerRe: ListView in UserControlmemberJani Giannoudis26 Apr '13 - 20:27 
You may access within your user-control the parent window to provide the saving context:
Window parentWindow = Window.GetWindow(userControlRefernce);
 
Member 9540155 wrote:
Thanks and great article!
Thanks a lot!
Cheers,
Jani Giannoudis
Meerazo.com - Resource Sharing Made Easy | Co-founder

QuestionUpgrading an obsolete settingsmemberKevinTipps18 Dec '12 - 5:27 
Hi Jani,
 
Great Article, just wondering if your code can deal with obsolete settings from a previous version via an upgrade.
 
e.g
I have a property call Age in V1.0 of the user config file and have changed it to NewAge in version 2.0
 
in the standard VS2010 I have had to create a partial class with Age in it and set it to [obsolete] to be able to call
NewAge = (uint)Setttings.GetPreviousVersion("Age");
in the Upgrade method.
I tried to implement something similar using your class but with no success.
 
Do you think this would be possible.
Regard
Ian AKA KevinTipps
GeneralMy vote of 5memberAlan G Banks14 Nov '12 - 0:04 
Excellent article, big help to me.
AnswerRe: My vote of 5mvpJani Giannoudis16 Nov '12 - 8:43 
Many thanks Alan. I'm glad I could help Smile | :)
Cheers,
Jani Giannoudis
Meerazo.com - Resource Sharing Made Easy | Co-founder

GeneralMy vote of 5memberdarkvain6 Nov '12 - 10:04 
Very Nice!!!
AnswerRe: My vote of 5mvpJani Giannoudis7 Nov '12 - 10:26 
Thanks a lot! Smile | :)
Cheers,
Jani Giannoudis
Meerazo.com - Resource Sharing Made Easy | Co-founder

QuestionNeed to save individual user settingsmemberdarkvain5 Nov '12 - 11:29 
First of all Excellent article.
I have a Windows form application which create a ton of checkboxes at runtime depending on user input and I needed a way to store the states of those checkboxes. This works wonderfully. But the user information is setup at runtime also and the checkbox states are being applied to all users. Is there a way to save the settings for different users?
AnswerRe: Need to save individual user settingsmemberdarkvain7 Nov '12 - 4:18 
Never mind I figured it out. I just needed to use the SettingsKey.
mySettings.SettingsKey = "user".
QuestionUser.config not updated when creating a new versionmemberhpo722 Oct '12 - 6:01 
Thank you very much, it's exactly what i was looking for.
But had a problem when creating a new version of my code; user.config was not updated.
Found, that the load process was called twice.
I removed the load() within WindowInitialized, now it seems to work perfect. (? may be i missed something ?)
private void WindowInitialized( object sender, EventArgs e )
{
    if ( UseLocation )
    {
        Settings.Add( topSetting );
        Settings.Add( leftSetting );
    }
    if ( UseSize )
    {
        Settings.Add( widthSetting );
        Settings.Add( heightSetting );
    }
    Load();
} // WindowInitialized

AnswerRe: User.config not updated when creating a new versionmvpJani Giannoudis9 Nov '12 - 21:39 
Hi hpo7
 
Many thanks for your feedback!
 
Unfortunately, I can't repdroduce this issue.
How did you change the application version?
Cheers,
Jani Giannoudis
Meerazo.com - Resource Sharing Made Easy | Co-founder

GeneralMy vote of 5membertomtom622 Aug '12 - 6:36 
Great, this is exactly what I needed -)
AnswerRe: My vote of 5mvpJani Giannoudis2 Aug '12 - 21:31 
Thanks tomtom62, I'm glad you can use it.
Cheers,
Jani Giannoudis
Meerazo.com - Resource Sharing Made Easy | Co-founder

QuestionStrange Behaviour on Xaml RibbonWindowmembertomtom622 Aug '12 - 6:35 
Hi Jani,
 
I'm using WindowsSettings on a Xaml Ribbon-Window. On every Save() 59px on the Top and 3px on the left are subtracted before saving the values.I don't move the window by myself, I only open the application and close it. The ribbon itself has a height of 59px. Do you have an idea on whats going wrong ?
 
Regards
 
Thomas
AnswerRe: Strange Behaviour on Xaml RibbonWindowmvpJani Giannoudis2 Aug '12 - 21:33 
Hi tomtom62
 
It seems to be a problem with the initialization and layout sequence. Do you have a simple example?
Cheers,
Jani Giannoudis
Meerazo.com - Resource Sharing Made Easy | Co-founder

GeneralRe: Strange Behaviour on Xaml RibbonWindowmembertomtom623 Aug '12 - 3:55 
Its just simple
 
public MainWindow()
 {
     this.windowSettings = new WindowSettings(this);
     this.windowSettings.SaveOnClose = false;
     this.myProgrammStart = new ProgrammStart(Debugmode);
 }
 
The ribbon is the first element in the window after the grid. Nothing special...
Other windows in the project (without a ribbon) do work as expected...
AnswerRe: Strange Behaviour on Xaml RibbonWindowmvpJani Giannoudis5 Aug '12 - 21:37 
Hi tomtom62
 
Unfortunately I don't have installed the Xaml RibbonWindow library. However, you can try to instantiate the WindowSettings class later, for example within the load event.
Cheers,
Jani Giannoudis
Meerazo.com - Resource Sharing Made Easy | Co-founder

QuestionSharing setting between user & Runtime modification: way of changing default value?memberyves_ozi19 Jul '12 - 16:17 
Hi Jani,
 
Thanks for your article: very useful and help me a lot to get a better understanding of this subject. I have still one question: how about having persistent settings, been able to be modified by user during Runtime, and shared between all user? It seem loads of people are facing this situation that is just a mix between the scopes available:

-Application scope settings are not meant to be modified during Runtime but are shared by all user.
-User scope settings have the advantage to be able to be modified during Runtime but of course... are user dependent!
 
With researching, it seems some people are using "brutal solution": they define the targetted settings with an application scope, and hardcode opening and modification of the app.config XML file during Runtime (as long as they don't have access restriction problem??): it's seem to me a little bit messy, but why not...
 
1-Path solution: Like some other, I was also thinking of keeping all the setting with a user scope and changing the storing path to share the same file between all the users. Is seems a good solution, but as I have also some "real" user dependant settings, it involve having two user.config files with two different path: I am not sure yet it is doable and a good practice?
 
2-Changing default values: Another solution would be to change the default value of the user settings to use them as a kind of "application scope" (by calling reset() in program launching). If I am right, all the modified user settings are stored in the user.config file (In the user Local directory). The default user settings are stored in the app.config file under a section userSettings. I don't know if it is possible to modify it during runtime and if so, I don't know how!! (With DefaultSettingValueAttribute !?) (To me, this section is different of the applicationSetting one that contains the application scope settings in read only during Runtime). This solution, if possible, seems to me the more practical and easy but again, not sure if best practice!!!)
 
Last solution would be to store the targeted parameters in a totally different file and not using the settings systems provide by VS. But, this is another story...
 
I hope my explanations were not too unclear!! Any comments or suggestions will be very helpful.
 
Cheers,
 
Yves
GeneralRe: Sharing setting between user & Runtime modification: way of changing default value?mvpJani Giannoudis19 Jul '12 - 16:29 
I'm on vacation until august. Cheers, Jani.
Cheers,
Jani Giannoudis
Meerazo.com - Resource Sharing Made Easy | Co-founder

GeneralMy vote of 5memberMohammad A Rahman22 May '12 - 17:43 
Fantastic article. My 5!
AnswerRe: My vote of 5mvpJani Giannoudis22 May '12 - 20:21 
Thank you Mohammad!
Cheers,
Jani Giannoudis
Meerazo.com - Resource Sharing Made Easy | Co-founder

GeneralWow wonderful article. My 5memberShannon McCoy29 Apr '12 - 19:44 
Thank you for this very well written, very well though out and useful article. You saved me a bunch of work.
AnswerRe: Wow wonderful article. My 5mvpJani Giannoudis30 Apr '12 - 5:54 
Hi Shannon
 
Many thanks for your feedback and vote!
Cheers,
Jani Giannoudis
Meerazo.com - Resource Sharing Made Easy | Co-founder

QuestionExpertly-written article - my vote of 5memberBrian C Hart21 Apr '12 - 5:15 
I am book marking this for later, because right now I am on a different task, but your article is very nicely done and really is spot-on.
Sincerely Yours,
Brian Hart

AnswerRe: Expertly-written article - my vote of 5mvpJani Giannoudis22 Apr '12 - 1:22 
Many thanks Brian, I'm glad you lie it!
Cheers,
Jani Giannoudis
Meerazo.com - Resource Sharing Made Easy | Co-founder

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Rant Rant    Admin Admin   

Permalink | Advertise | Privacy | Mobile
Web04 | 2.6.130516.1 | Last Updated 21 Apr 2012
Article Copyright 2008 by Jani Giannoudis
Everything else Copyright © CodeProject, 1999-2013
Terms of Use
Layout: fixed | fluid