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.
Comments