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.