Posts Tagged ‘usersettings’

WPF: User settings anyone?

May 11, 2008

I wanted to knock up a simple window to view and edit all the available user settings for an application. I thought this would be a nice article as it shows how to make use of the DataSourceProvider and ObservableCollection.

The first step was to get the settings (SettingsPropertyCollection) into something more manageable.

public class UserSettingsCollection : ObservableCollection<UserSetting> { public UserSettingsCollection(SettingsPropertyCollection settings) : base() { foreach (SettingsProperty prop in settings) { UserSetting setting = new UserSetting(prop.Name, prop.DefaultValue); if (!base.Contains(setting)) { base.Add(setting); } } } }

The UserSetting object starts out very simple (Name/Value) but you will probably want to add some validation and notify the UI when something has changed.

public class UserSetting { public UserSetting(string name, object value) { Name = name; Value = value; } public string Name { get; set; } public object Value { get; set; } }

The only other object I required was some sort of provider to handle the reading and writing of the settings which I called the UserSettingsProvider.

public class UserSettingsProvider : DataSourceProvider { private UserSettingsCollection _settings; protected override void BeginQuery() { _settings = new UserSettingsCollection(Properties.User.Default.Properties); base.OnQueryFinished(_settings); } public void Save() { foreach (UserSetting setting in _settings) { Properties.User.Default.Properties[setting.Name].DefaultValue = setting.Value; } Properties.User.Default.Save(); } }

The XAML is pretty straightforward mainly because it is not my strong point and partly because I just created it manually and therefore didn’t pimp it up in Blend!

<Window.Resources> <ResourceDictionary> <local:UserSettingsProvider x:Key="settingsProvider"/> </ResourceDictionary> </Window.Resources> <Grid> <DockPanel DataContext="{StaticResource settingsProvider}"> <ItemsControl DockPanel.Dock="Top" ItemsSource="{Binding Path=.}"> <ItemsControl.ItemsPanel> <ItemsPanelTemplate> <WrapPanel /> </ItemsPanelTemplate> </ItemsControl.ItemsPanel> <ItemsControl.ItemTemplate> <DataTemplate> <StackPanel Orientation="Vertical"> <Label x:Name="NameLabel" Content="{Binding Path=Name}"/> <TextBox x:Name="ValueTextBox" Text="{Binding Path=Value}" Width="200"/> </StackPanel> </DataTemplate> </ItemsControl.ItemTemplate> </ItemsControl> <Button x:Name="SaveButton" Content="Save" Command="Save" Height="20" Width="50" /> </DockPanel> </Grid>

Only thing worth noting here is that the UserSettingsProvider is bound to the DockPanel (not the ItemsControl). I basically did this so I could pick up the provider from the button’s DataContext when executing the save command like so:

public partial class UserSettings : Window { public UserSettings() { InitializeComponent(); CommandBinding saveCommand = new CommandBinding(); saveCommand.Command = ApplicationCommands.Save; saveCommand.CanExecute += this.CanExecuteSave; saveCommand.Executed += this.Save; this.CommandBindings.Add(saveCommand); } private void Save(object sender, ExecutedRoutedEventArgs e) { Button button = e.OriginalSource as Button; UserSettingsProvider provider = button.DataContext as UserSettingsProvider; if (provider == null) { throw new NullReferenceException("Failed to access the user settings provider."); } provider.Save(); } private void CanExecuteSave(object sender, CanExecuteRoutedEventArgs e) { e.CanExecute = true; } }

When it is all put together you get a simple little dialog like this.


I haven’t posted any code files to download for this one because all the code is shown here.

If you did want to take it further and add custom validation or fancy up the UI then feel free to let me know how you get on.


Josh Smith: Binding to the file system