Collection Controls with Rich Design Time Support

Wrapping Up

Removing Buttons

This is another question of playing nicely with the designers. We will be writing the code to go in the OnComponentRemoving function in our designer. We need to handle two things in here. Firstly, the user removing the main control. When this happens we need to destroy all the buttons that are on the design surface. Secondly, when the user removes a button by selecting it and pressing delete. We need to remove it from the Button collection when this happens. Again, any changes we make to anything need to be wrapped in OnComponentChanging and OnComponentChanged calls.

VB.NET

Private Sub OnComponentRemoving(ByVal sender As Object, ByVal e As ComponentEventArgs)
    Dim c As IComponentChangeService = DirectCast(GetService(GetType _
    (IComponentChangeService)), IComponentChangeService)
    Dim button As ColourButton
    Dim h As IDesignerHost = DirectCast(GetService(GetType(IDesignerHost)), IDesignerHost)
    Dim i As Integer
    'If the user is removing a button
    If TypeOf e.Component Is ColourButton Then
        button = DirectCast(e.Component, ColourButton)
        If MyControl.Buttons.Contains(button) Then
            c.OnComponentChanging(MyControl, Nothing)
            MyControl.Buttons.Remove(button)
            c.OnComponentChanged(MyControl, Nothing, Nothing, Nothing)
            Return
        End If
    End If
    'If the user is removing the control itself
    If e.Component Is MyControl Then
        For i = MyControl.Buttons.Count - 1 To 0 Step -1
            button = MyControl.Buttons(i)
            c.OnComponentChanging(MyControl, Nothing)
            MyControl.Buttons.Remove(button)
            h.DestroyComponent(button)
            c.OnComponentChanged(MyControl, Nothing, Nothing, Nothing)
        Next
    End If
End Sub

C#

private void OnComponentRemoving(object sender, ComponentEventArgs e)
{
    IComponentChangeService c = (IComponentChangeService)
    GetService(typeof(IComponentChangeService));
    ColourButton button;
    IDesignerHost h = (IDesignerHost) GetService(typeof(IDesignerHost));
    int i;
    // If the user is removing a button
    if (e.Component is ColourButton)
    {
        button = (ColourButton) e.Component;
        if (MyControl.Buttons.Contains(button))
        {
            c.OnComponentChanging(MyControl, null);
            MyControl.Buttons.Remove(button);
            c.OnComponentChanged(MyControl, null, null, null);
            return;
        }
    }
    // If the user is removing the control itself
    if (e.Component == MyControl)
    {
        for (i = MyControl.Buttons.Count - 1; i >= 0; i--)
        {
            button = MyControl.Buttons[i];
            c.OnComponentChanging(MyControl, null);
            MyControl.Buttons.Remove(button);
            h.DestroyComponent(button);
            c.OnComponentChanged(MyControl, null, null, null);
        }
    }
}

Now that we've added that code, the user can delete buttons visually as they would delete any other control or component on the design surface. Also, Undo and Redo now work when adding buttons.

Conclusion

We have created the basics of a toolbar control with rich design time support. Adding more properties to the buttons is easy compared to the code we've had to write to enable this support. I hope you've found this article useful, it has certainly demonstrated a lot of the techniques you'll use when writing both design time and runtime code. The toolbar doesn't actually do anything at run time except sit there and look pretty, but we already have the elements in place to add support for mouseovers and a ButtonClick event.

I have provided a solution with both a VB and C# project, which are functionally identical.

You might also like...

Comments

Contribute

Why not write for us? Or you could submit an event or a user group in your area. Alternatively just tell us what you think!

Our tools

We've got automatic conversion tools to convert C# to VB.NET, VB.NET to C#. Also you can compress javascript and compress css and generate sql connection strings.

“We should forget about small efficiencies, say about 97% of the time: premature optimization is the root of all evil.” - Donald Knuth