Skip to content

Adding a Custom StyleCop Settings Page

Christophe HEISER edited this page Aug 16, 2015 · 4 revisions
Adding a Custom StyleCop Settings Page
Example 

StyleCop provides a mechanism for custom rules analyzers to expose settings pages containing advanced options, allowing the user to control the behavior of rules. An end-user can access the custom settings page by right-clicking on a project in Visual Studio and selecting the StyleCop Settings menu item, then switching to the custom settings page.

This topic assumes that you have already built a custom StyleCop rules project, as described within the Writing Custom Rules for StyleCop topic.

Building a Custom StyleCop Settings Page

  1. Before creating a custom settings page, define the properties the user will configure on the page, as described in the Adding Custom Rule Settings topic.

  2. After defining the custom properties for your rules analyzer, open the project containing your rules analyer in Visual Studio and add a new UserControl to the project.

  3. Add UI controls to the new UserControl which the user will interact with to set the appropriate settings for your rules analyzer.

  4. Make the UserControl class implement the IPropertyControlPage interface.

    Code
    public partial class MyCustomSettingsPage : UserControl, IPropertyControlPage
                
  5. Pass an instance of your custom rules analyzer into the constructor of the settings page class, and save it.

    Code
    public MyCustomSettingsPage(MyCustomRulesAnalyzer analyzer)
    {
        this.analyzer = analyzer;
    }
              
  6. Implement the Initialize(PropertyControl) method. This method is called by the framework to allow the settings page to load the current settings and initialize the controls on the page. The framework will pass an instance of the PropertyControl which is hosting the page. This reference should be saved for later use.

    Code
    public void Initialize(PropertyControl propertyControl)
    {
        // Save the property control.
        this.tabControl = propertyControl;
    
    // Load the current settings and initialize the controls on the form.
    this.InitializeSettings();
    
    // Put the form into 'not-dirty' state.
    this.dirty = false;
    this.tabControl.DirtyChanged();
    

    }

    private void InitializeSettings() { // Load the current setting of my custom string property. StringProperty customSettingProperty = this.analyzer.GetSetting( this.tabControl.MergedSettings, "MyCustomPropertyName") as StringProperty;

    if (companySettingProperty != null)
    {
        // Set the value of the property into an edit box on the page.
        this.customPropertyEditBox.Text = companySettingProperty.Value;
    }
    

    }

  7. Implement the Apply method. This method is called by the framework when the user selects the OK or Apply buttons on the settings dialog. The custom settings page should save any settings changes made by the user.

    Code
    public bool Apply()
    {
    if (this.analyzer != null)
    {
    if (this.customPropertyEditBox.Text.Length == 0)
    {
    this.analyzer.ClearSetting(this.tabControl.LocalSettings, "MyCustomPropertyName");
    }
    else
    {
    this.analyzer.SetSetting(
    this.tabControl.LocalSettings,
    new StringProperty(this.analyzer, "MyCustomPropertyName", this.customPropertyEditBox.Text));
    }
    }
    
    this.dirty = false;
    this.tabControl.DirtyChanged();
    
    return true;
    

    }

  8. Implement event handlers for each control on the page, and set the dirty property whenever the user changes a setting on the page.

    Code
    private void CustomPropertyEditBoxTextChanged(object sender, System.EventArgs e)
    {
    this.dirty = true;
    this.tabControl.DirtyChanged();
    }
    
  9. Implement the Dirty property. This property is accessed by the framework to determine whether the user has changed any setting on the page.

    Code
    public bool Dirty
    {
    get { return this.dirty; }
    
    set
    {
        if (this.dirty != value)
        {
            this.dirty = value;
            this.tabControl.DirtyChanged();
        }
    }
    

    }

  10. Implement each of the other members of the IPropertyControlPage interface (most can be left empty).

  11. Implement an override of the SettingsPages property within your custom rules analyzer class, and return an instance of your new settings page.

    Code
    public override ICollection<IPropertyControlPage> SettingsPages
    {
    get
    {
    return new IPropertyControlPage[] { new MyCustomSettingsPage(this) };
    }
    }
    

Example

Code
namespace MyCustomNamespace
{
using System;
using System.Drawing;
using System.Windows.Forms;
using StyleCop;
public partial class MyCustomSettingsPage : UserControl, IPropertyControlPage
{
    private PropertyControl tabControl;
    private bool dirty;
    private MyCustomRulesAnalyzer analyzer;

    public MyCustomSettingsPage(MyCustomRulesAnalyzer analyzer)
    {
        this.analyzer = analyzer;
    }

    public string TabName
    {
        get { return "My Settings"; }
    }

    public bool Dirty
    {
        get 
        { 
            return this.dirty; 
        }

        set
        {
            if (this.dirty != value)
            {
                this.dirty = value;
                this.tabControl.DirtyChanged();
            }
        }
    }

    public void Initialize(PropertyControl propertyControl)
    {
        this.tabControl = propertyControl;

        this.InitializeSettings();

        this.dirty = false;
        this.tabControl.DirtyChanged();
    }

    public bool PreApply()
    {
        return true;
    }

    public void PostApply(bool wasDirty)
    {
    }

    public bool Apply()
    {
        if (this.analyzer != null)
        {
            if (this.customPropertyEditBox.Text.Length == 0)
            {
                this.analyzer.ClearSetting(this.tabControl.LocalSettings, "MyCustomPropertyName");
            }
            else
            {
                this.analyzer.SetSetting(
                    this.tabControl.LocalSettings,
                    new StringProperty(this.analyzer, "MyCustomPropertyName", this.customPropertyEditBox.Text));
            }
        }

        this.dirty = false;
        this.tabControl.DirtyChanged();

        return true;
    }

    public void Activate(bool activated)
    {
    }

    public void RefreshSettingsOverrideState()
    {
    }

    private void InitializeSettings()
    {
        // Load the current setting of my custom string property.
        StringProperty customSettingProperty = this.analyzer.GetSetting(
            this.tabControl.MergedSettings, "MyCustomPropertyName") as StringProperty;

        if (companySettingProperty != null)
        {
            // Set the value of the property into an edit box on the page.
            this.customPropertyEditBox.Text = companySettingProperty.Value;
        }
    }

    private void CustomPropertyEditBoxTextChanged(object sender, System.EventArgs e)
    {
        this.dirty = true;
        this.tabControl.DirtyChanged();
    }
}

}

Clone this wiki locally