Skip to content
Daniel Cazzulino edited this page Jan 9, 2014 · 2 revisions

Allowing the user to configure the functionality provided by your extension is a fairly common scenario, and therefore Clide provides a very straightforward way to implement it.

Clide separates the concept of the settings values themselves, from the UI that may be used to edit them. So the first thing is to create a class inheriting from Settings that contains the values you want to allow configuration for:

[Settings]
public class ServerSettings : Settings, IServerSettings
{
    public ServerSettings(ISettingsManager manager)
        : base(manager)
    {
    }

    [Required]
    public Uri Address { get; set; }

    [DefaultValue(8080)]
    [Required]
    [Range(8000, 50000)]
    public int Port { get; set; }
}

Note how you can leverage Data Annotations to add automatic validation. The base Settings class implements all the necessary initialization, reading, editing, cancelling and saving of these settings to the Visual Studio settings store.

In order for the automatic properties approach shown above to work, you need to install the Property Changed nuget package, which automatically provides the required property changed notifications. Otherwise, you must use regular properties and invoke the base RaisePropertyChanged method as needed.

The above sample implements an interface, which allows other components to just take a constructor dependency on the settings thanks to the built-in Composition. This makes the settings consuming code easily testable.

If no UI is provided to edit the settings, your code can do it directly by changing the property values and calling Save on it. Alternatively, the values can also be edited manually via the registry. If the above class was in the Contoso.Tools namespace, the corresponding registry key for Visual Studio 2012 would be under HKCU\Software\Microsoft\VisualStudio\12.0\Contoso\Tools\ServerSettings, with a string value for each of the properties. .NET's generalized type conversion is used, so in addition to the built-in type converters, and you can also provide custom string conversion for complex types if needed.

Settings Editing

Clide provides out of the box support for WPF views that directly data-bind to the settings class, significantly simplifying the task of providing a front-end for editing your settings. You just create a straightforward WPF user control that uses binding expressions against the underlying settings model:

<UserControl x:Class="SamplePackage.ServerSettingsView"
             xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
             xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
             xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
             xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 
             mc:Ignorable="d" 
             d:DesignHeight="183" d:DesignWidth="323">
    <StackPanel Orientation="Vertical">
        <TextBlock Text="Address:" VerticalAlignment="Top" Margin="5" />
        <TextBox Text="{Binding Address}" Width="100" Margin="5" VerticalAlignment="Top" HorizontalAlignment="Left" />
        <TextBlock Text="Port:" VerticalAlignment="Top" Margin="5" />
        <TextBox Text="{Binding Port}" Width="100" Margin="5" VerticalAlignment="Top" HorizontalAlignment="Left" />
    </StackPanel>
</UserControl>

If you intend to show this UI in the Tools | Options dialog in Visual Studio (which is most common), you simply provide an OptionsPage-derived class that binds together the settings and the view types:

[Category("My Package")]
[DisplayName("Server Settings")]
[OptionsPage]
public class ServerSettingsPage : OptionsPage<ServerSettingsView, ServerSettings>
{
    public ServerSettingsPage(IOptionsPageWindowFactory windowFactory, ServerSettings settings)
        : base(windowFactory, settings)
    {
    }
}

With this class in place and nothing else, you will get the following fully working settings editing experience:

Sample Tools Options

Table of Contents


- [How To Code Samples][1]
Clone this wiki locally