Winforms tools for selection of items using ComboBox - binding datasource This is mi UserControl containing ComboBox and few buttons for selecting and manipulating collection of items which implement simple interface IHasHeader (just header with name and ID).

It works now but I feel that I use some not ideal hacks, especially in the area of binding of ComboBox's datasource. I'll be glad for any review notes.

public partial class TemplateSelector : UserControl
{
    /// &lt;summary&gt;
    /// Type of access right
    /// &lt;/summary&gt;
    public enum TemplateType
    {
        Private,
        Public
    }

    private BindingSource bindSrc = new BindingSource();
    private IHasHeader SelectedItem;
    private bool doHandleSelection = true;

    // delegates

    public delegate void ItemSelectedHandler(IHasHeader item);
    public delegate void NewTemplateSelectionHandler(string name, bool isPublic);
    public delegate void NameSelectionHandler(string name);

    // events

    public event ItemSelectedHandler TemplateSelectionChanged = delegate { };
    public event NameSelectionHandler TemplateDeleting = delegate { };
    public event NewTemplateSelectionHandler CreatingNewTemplate = delegate { };
    public event Action RefreshingTemplatesList = delegate { };
    public event Action ClearingTemplate = delegate { };

    public TemplateType SelectedTemplateType { get; set; }

    public IEnumerable&lt;IHasHeader&gt; TemplatesDatasource
    {
        set
        {
            doHandleSelection = false;
            bindSrc.DataSource = value;
            cboxTemplates.DataSource = bindSrc;
            cboxTemplates.SelectedIndex = -1;
            doHandleSelection = true;
        }
    }

    public TemplateSelector()
    {
        InitializeComponent();
        cboxTemplates.SelectedIndexChanged += cboxTemplates_SelectedIndexChanged;
    }

    /// &lt;summary&gt;
    /// Select given item
    /// &lt;/summary&gt;
    /// &lt;param name="item"&gt;&lt;/param&gt;
    public void SelectItem(IHasHeader item)
    {
        for (int i = 0; i &lt; cboxTemplates.Items.Count; ++i)
        {
            if ((cboxTemplates.Items[i] as IHasHeader).Header.ID == item.Header.ID)
            {
                SelectedItem = item;
                cboxTemplates.SelectedIndex = i;
                return;
            }
        }
    }

    /// &lt;summary&gt;
    /// Clear selection of combobox
    /// &lt;/summary&gt;
    public void ClearSelection()
    {
        cboxTemplates.SelectedIndex = -1;
        SelectedItem = null;
    }

    /// &lt;summary&gt;
    /// Add item to combobox datasource
    /// &lt;/summary&gt;
    /// &lt;param name="item"&gt;&lt;/param&gt;
    public void AddItem(IHasHeader item)
    {
        var newSource = (bindSrc.DataSource as IEnumerable&lt;IHasHeader&gt;).ToList();
        newSource.Add(item);
        TemplatesDatasource = newSource;
    }


    private void btnDelete_Click(object sender, EventArgs e)
    {
        if (cboxTemplates.SelectedItem is IHasHeader)
        {
            IHasHeader selected = cboxTemplates.SelectedItem as IHasHeader;
            TemplateDeleting(selected.Header.Name);
            bindSrc.ResetBindings(false);
        }
        ClearSelection();
        ClearingTemplate();
    }

    private void btnNew_Click(object sender, EventArgs e)
    {
        CreatingNewTemplate(TextBoxNewTemplateNew.Text, RadioButtonMeasureQuantitySaveSettingsPublic.Checked);
        bindSrc.ResetBindings(false);
    }

    private void cboxTemplates_SelectedIndexChanged(object sender, EventArgs e)
    {
        if (cboxTemplates.SelectedItem is IHasHeader &amp;&amp; doHandleSelection)
        {
            IHasHeader selected = cboxTemplates.SelectedItem as IHasHeader;
            TemplateSelectionChanged(selected);
        }
    }

    private void btnRefresh_Click(object sender, EventArgs e)
    {
        RefreshingTemplatesList();
        bindSrc.ResetBindings(false);
        cboxTemplates.SelectedItem = SelectedItem;
    }

    private void btnClear_Click(object sender, EventArgs e)
    {
        ClearSelection();
        ClearingTemplate();
    }
}
Style &amp; Conventions


Enums and delegates shouldn't be nested in a class.
The default event delegate is the EventHandler. If you want to create a custom event handler then its signature should be 

delegate void ItemSelectedHandler(Object sender, EventArgs e);



but if you need custom event args then you should create a new class derived from EventArgs and with the properties that you need:

class SelectEventArgs : EventArgs
{
    ..ctor
    public IHasHeader item { get; }
}


then you can use the generic event-handler:

public event EventHandler&lt;SelectEventArgs&gt; TemplateSelectionChanged = delegate { };


You shouldn't use any other pattern for events like


public event Action RefreshingTemplatesList = delegate { };



If you want to follow the event style and conventions then stick to the EventHandler and event args.



Binding


public IEnumerable&lt;IHasHeader&gt; TemplatesDatasource
{
  set
  {
      doHandleSelection = false;
      bindSrc.DataSource = value;
      cboxTemplates.DataSource = bindSrc;
      cboxTemplates.SelectedIndex = -1;
      doHandleSelection = true;
  }
}



here you could write

 bindSrc.DataSource = value.ToList();


instead


bindSrc.DataSource = value;



so that you can later reuse this list for adding more items:

public void AddItem(IHasHeader item)
{
    var headers = bindSrc.DataSource as List&lt;IHasHeader&gt;;
    headers.Add(item);
    bindSrc.ResetBindings(false);
}


Don't abbreviate the names like bindSrc. Use full names and preferably meaninigful ones like headerSource or headerBindingSource. bindSrc doesn't say anything about what the binding source holds.