Creating a dynamic SharePoint settings DropDown using a ToolPart

In order to create a dropdown in the settings view of SharePoint it is required that you use an enum with the out-of-box behavior. Each enum item will be presented as an item in the dropdown.

What happens if you want to have a dropdown that is generated dynamically each time the settings window is opened? Enter the world of custom ToolParts.

A toolpart is a sub-section of the settings window when you go to edit the settings of a webpart. Unfortunately they are not easily customizable to flow in with your other settings, so I actually ended up moving all of my settings to the custom toolpart, just for consistency.

Using a custom toolpart requires that you do two things:
1. Create a class that overrides Microsoft.SharePoint.WebPartPages.ToolPart
2. Override the GetToolParts section of your WebPart

I will step through each of these.

In order to create your custom toolpart, you must create a class that overrides Microsoft.SharePoint.WebPartPages.ToolPart. My example code is posted below with comments inline:

public class MyToolPart : Microsoft.SharePoint.WebPartPages.ToolPart
{
// This is the actual dropdown control
System.Web.UI.WebControls.DropDownList m_Dropdown = new System.Web.UI.WebControls.DropDownList();
// Reference to the parent web part
MyWebPart m_Parent = null;

public MyToolPart()
{
// Set the title of our toolpart
this.Title = "Settings";
}

protected override void CreateChildControls()
{
// Get the instance of the web part
m_Parent = (MyWebPart)ParentToolPane.SelectedWebPart;

// Add some items to the dropdown, this is also where you would dynamically populate any items to add
m_Dropdown.Items.Add("One");
m_Dropdown.Items.Add("Two");
m_Dropdown.Items.Add("Three");

// Add the dropdown to the actual toolpart controls
this.Controls.Add(m_Dropdown);

base.CreateChildControls();
}

public override void ApplyChanges()
{
// Set the value on apply. This is using a public property on the webpart
m_Parent.MyValue = m_Dropdown.SelectedValue;
}
}

Now we need to manipulate the web part class so that it works with the toolpart:

// This is what we use to set the value from the toolpart's ApplyChanges() method
public string MyValue
{
get
{
return m_MyValue;
}
set
{
m_MyValue = value;
}
}

protected override void Render(HtmlTextWriter writer)
{
// Normal web part code would be here. You could then use the set value from the toolpart in your code as you normally would with a property from a web part

Compile this as you normally would for a web part, deploy, and you're good to go.

A note about the sequence of layout in these toolparts: They appear in the direction in which they were added. So in the case of my array above, the custom toolpart would appear last in the settings zone.