Introduction
The Property Settings capability provided by Visual Studio is quite good for many applications, but is not able to support Application level changes where several applications use the same code base. This paper covers a way to provide each application with its own settings that can be easily maintained.
Background
We had several applications that could use the same Views but for slight differences. To accommodate the requirements for the different applications, we could have created new views, or add properties to the ViewModel
, and use these properties in the Views. This added unnecessary complexity to the ViewModels
, and also might require some way of customizing the ViewModel
for each application when it would otherwise not be required. There are also a lot of other disadvantages to using Binding, including performance, and maintenance as images change in the Views.

One of the thoughts was to use the existing Settings. This would have allowed all the paths for the icons to be specified in the Settings file, and the XAML in the view could directly access these settings. However, this did not work well on an application level. We could have created different settings files for each application, but then would have to include the right settings files in the build. The final solution was to use a static
class with static
properties, and then update those properties. This has a lot of the advantages of the Setting approach, and each application could easily customize the values in this static
class.
Implementation
The Settings
file has to be static
so that it is possible to bind to it from XAML without it interfering with the current DataContext
. Thus by warping the settings in static
properties, the following XAML will work where the namespace for the settings class is WpfDynamicSettings
, and the name of the class is ApplicationSettings
:
<Window x:Class="WpfDynamicSettings.TestWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:settings="clr-namespace:WpfDynamicSettings"
Title="TestWindow" Height="200" Width="300">
<Window.Resources>
<settings:ApplicationSettings x:Key="Settings"/>
</Window.Resources>
<StackPanel HorizontalAlignment="Center" VerticalAlignment="Center">
<TextBlock Text="{Binding String1, Source={StaticResource Settings}}"
Width="200" Margin="10"/>
<TextBlock Text="{Binding String2, Source={StaticResource Settings}}"
Width="200" Margin="10"/>
</StackPanel>
</Window>
NOTE: I like to put the “xmlns:settings
” and the “settings:ApplicationSettings
” in the App.xaml resource or a dictionary referred to by the App.xaml file so that these lines only have to be defined once in the application.
The ApplicationSettings file can be quite simple, but there has to be some way to update the values for the settings, and for this I use a method I named Update
:
public class ApplicationSettings
{
public static string String1 { get; protected set; }
public static string String2 { get; protected set; }
static ApplicationSettings()
{
String1 = String1 ?? "Default 1";
String2 = String2 ?? "Default 2";
}
public static void Update (string string1 = null, string string2 = null)
{
String1 = string1 ?? String1;
String2 = string2 ?? String2;
}
}
The constructor is only required if there are to be default values (required for our use since it meant that the legacy applications did not have to be changed to support the updated Views).
The method “Update
” is only needed for one of the ways of initializing the ApplicationSettings
file to the values for the specific application. Note: I made all arguments optional, and then only updated corresponding properties if they were not null
, not changing the current value. This supports named arguments, which I think is much clearer:
ApplicationSettings.Update(
string1: "Updated Application 1 String 1",
string2: "Updated Application 1 String 2");
It also allows specifying only those settings that need to be changed, giving a tremendous flexibility. If this is the only way the user wants to update the ApplicationSettings
, then all the properties can use a private
set instead of a protected
set. The protected
set is for using a derived class to update the values:
class Custom1ApplicationSettings : ApplicationSettings
{
static Custom1ApplicationSettings()
{
String1 = "Custom 1 String 1";
String2 = "Custom 1 String 2";
}
public static void Update()
{
String1 = "Custom 1 String 1";
String2 = "Custom 1 String 2";
}
}
The constructor is not required, and in fact should not be in the class since if the Update
method is used, it is redundant. The interesting thing is that the constructor for the parent class only executes after the Update
for the derived class has executed. This is the reason the “??” operator is used in setting all the default values for the constructor in the parent class. However, when the Update
in the parent class is called, the constructor executes first. This is the reason that the “??” operator is used in the parent class’s Update
method so the Update
method does not overwrite the default values with null
.
For my needs, I wanted the ApplicationSettings
class to be initialized when the application started, so updated the App.xaml to handle the Startup
event as follows:
<Application x:Class="WpfDynamicSettings.App"
xmlns=http://schemas.microsoft.com/winfx/2006/xaml/presentation
xmlns:x=http://schemas.microsoft.com/winfx/2006/xaml
Startup="AppStartup"
StartupUri="MainWindow.xaml">
<Application.Resources>
</Application.Resources>
</Application>
Then I added an event handler in the App.xaml.cs file that would initialize the ApplicationSettings
file either using the class method:
public partial class App : Application
{
private void AppStartup(object sender, StartupEventArgs e)
{
Custom1ApplicationSettings.Update();
}
}
Or using the Update
method on the base class as follows:
public partial class App : Application
{
private void AppStartup(object sender, StartupEventArgs e)
{
ApplicationSettings.Update(
string1: "Initialized in App startup 1",
string2: "Initialized in App startup 2");
}
}
The example I created has a combo box which allows the user to select whether to open a new form either using the Update
method with the settings specified in the arguments in the base class, or the Update
method in a derived class with the settings specified in the derived class. There are two different settings for each implementation. Also the App.xaml has code to set the settings, and code for both is in the App.xaml.cs file. We can enable either method, or disable both to see the results. The form that is used to demonstrate the concept is below. Just select the option from the combo box and the second window will be displayed. Use the close button to return to the first form.


Summary
This design has successfully met our needs for Application level settings without having to do anything special during build, or modifying the Settings file for each application derived from the common base.
History
- 2011/10/05: Initial version
Has been working as a C# developer on contract for the last several years, including 3 years at Microsoft. Previously worked with Visual Basic and Microsoft Access VBA, and have developed code for Word, Excel and Outlook. Started working with WPF in 2007 when part of the Microsoft WPF team. For the last eight years has been working primarily as a senior WPF/C# and Silverlight/C# developer. Currently working as WPF developer with BioNano Genomics in San Diego, CA redesigning their UI for their camera system. he can be reached at qck1@hotmail.com.