[RESOLVED] Subclass BindingNavigator - Strange behavior
Hello all,
One of the VBF member was asking how to add a close button on the BindingNavigator control once and reuse it on all other forms, so I try to create a custom bindingnavigator class that inherits the BindingNavigator class.
Below is the inherited class:
vb.net Code:
Public Class BindingNavigatorEx
Inherits System.Windows.Forms.BindingNavigator
Public Sub New()
MyBase.New()
'Add the closeform button
Dim closeButton As New ToolStripButton("Close", Nothing, New EventHandler(AddressOf CloseForm_OnClick))
Me.Items.Add(closeButton)
'Add a separator
Dim separator As New ToolStripSeparator()
separator.Size = New System.Drawing.Size(6, 25)
Me.Items.Add(separator)
End Sub
Private Sub CloseForm_OnClick(ByVal sender As Object, ByVal e As System.EventArgs)
'Find the outer most parent container control and trycast it to a form
'and call the close method on that form
Dim parent As Form = Nothing
Dim child As Control = Me
Dim ctrl As Control = Me.Parent
Do Until ctrl Is Nothing
child = ctrl
ctrl = ctrl.Parent
Loop
parent = TryCast(child, Form)
If parent IsNot Nothing Then
parent.Close()
End If
End Sub
End Class
The thing that I can't figure out is that it looks OK in design mode, but at run time, the custom binding navigator shows 2 "Close" buttons. Only one of them will close the form when clicked, the other one doesn't function. See the attached image.
Any ideas?
Re: Subclass BindingNavigator - Strange behavior
I know what is happening, and there is a workaround for it. When you add that inherited BindingNavigator to the form (container) it will run a call to New (obviously) so that's where it adds the first close button. Then if you take a look at the Designer generated code for the BindingNavigator you will see in there somewhere this:
vb.net Code:
'
'BindingNavigatorEx1
'
Me.BindingNavigatorEx1.AddNewItem = Me.BindingNavigatorAddNewItem
Me.BindingNavigatorEx1.CountItem = Me.BindingNavigatorCountItem
Me.BindingNavigatorEx1.DeleteItem = Me.BindingNavigatorDeleteItem
'**Delete Me.ToolStripButton1 from next line**
Me.BindingNavigatorEx1.Items.AddRange(New System.Windows.Forms.ToolStripItem() {Me.ToolStripButton1, _
Me.BindingNavigatorMoveFirstItem, _
Me.BindingNavigatorMovePreviousItem, _
Me.BindingNavigatorSeparator, _
Me.BindingNavigatorPositionItem, _
Me.BindingNavigatorCountItem, _
Me.BindingNavigatorSeparator1, _
Me.BindingNavigatorMoveNextItem, _
Me.BindingNavigatorMoveLastItem, _
Me.BindingNavigatorSeparator2, _
Me.BindingNavigatorAddNewItem, _
Me.BindingNavigatorDeleteItem})
Me.BindingNavigatorEx1.Location = New System.Drawing.Point(0, 0)
Me.BindingNavigatorEx1.MoveFirstItem = Me.BindingNavigatorMoveFirstItem
Me.BindingNavigatorEx1.MoveLastItem = Me.BindingNavigatorMoveLastItem
Me.BindingNavigatorEx1.MoveNextItem = Me.BindingNavigatorMoveNextItem
Me.BindingNavigatorEx1.MovePreviousItem = Me.BindingNavigatorMovePreviousItem
Me.BindingNavigatorEx1.Name = "BindingNavigatorEx1"
Me.BindingNavigatorEx1.PositionItem = Me.BindingNavigatorPositionItem
Me.BindingNavigatorEx1.Size = New System.Drawing.Size(1189, 25)
Me.BindingNavigatorEx1.TabIndex = 0
Me.BindingNavigatorEx1.Text = "BindingNavigatorEx1"
'
'ToolStripButton1 **Delete these lines**
'
Me.ToolStripButton1.Name = "ToolStripButton1"
Me.ToolStripButton1.Size = New System.Drawing.Size(37, 22)
Me.ToolStripButton1.Text = "Close"
If you notice, it is creating code for the Close button that you added when you added the BindingNavigator to the form. So when the application actually gets run, it will create the first button on the call to New, and then the second button in this code here. The workaround is to just delete the Designer code for that ToolStripButton.
I'm not sure how to prevent the Designer from generating the code for that button.
Re: Subclass BindingNavigator - Strange behavior
Here's another workaround actually, you don't have to mess with designer code, you just won't see the Button until the application is run:
vb.net Code:
Public Class BindingNavigatorEx
Inherits System.Windows.Forms.BindingNavigator
Public Sub New()
MyBase.New()
End Sub
Private Sub CloseForm_OnClick(ByVal sender As Object, ByVal e As System.EventArgs)
'Find the outer most parent container control and trycast it to a form
'and call the close method on that form
Dim parent As Form = Nothing
Dim child As Control = Me
Dim ctrl As Control = Me.Parent
Do Until ctrl Is Nothing
child = ctrl
ctrl = ctrl.Parent
Loop
parent = TryCast(child, Form)
If parent IsNot Nothing Then
parent.Close()
End If
End Sub
Protected Overrides Sub InitLayout()
MyBase.InitLayout()
If Not Me.DesignMode Then
Dim closeButton As New ToolStripButton("Close", Nothing, New EventHandler(AddressOf CloseForm_OnClick))
Me.Items.Add(closeButton)
End If
End Sub
End Class
Re: Subclass BindingNavigator - Strange behavior
I re-read the documentation for BindingNavigator and found out what I was doing wrong.
I should've overridden the AddStandardItems method and insert the button there.
So this is the re-done code and it works 100%.
vb.net Code:
Public Class BindingNavigatorEx
Inherits System.Windows.Forms.BindingNavigator
Private WithEvents _CloseForm As ToolStripItem = Nothing
Public Property CloseFormItem() As ToolStripItem
Get
Return _CloseForm
End Get
Set(ByVal value As ToolStripItem)
_CloseForm = value
End Set
End Property
Public Sub New()
MyBase.New()
End Sub
Public Overrides Sub AddStandardItems()
Me._CloseForm = New ToolStripButton("Close")
Me._CloseForm.Name = "ToolStripButtonCloseForm"
Me.Items.Add(Me._CloseForm)
'Add a separator
Dim separator As New ToolStripSeparator()
Me.Items.Add(separator)
MyBase.AddStandardItems()
End Sub
Private Sub _CloseForm_Click(ByVal sender As Object, ByVal e As System.EventArgs) Handles _CloseForm.Click
If Me.DesignMode = False Then
'Find the outer most parent container control and trycast it to a form
'and call the close method on that form
Dim parent As Form = Nothing
Dim child As Control = Me
Dim ctrl As Control = Me.Parent
Do Until ctrl Is Nothing
child = ctrl
ctrl = ctrl.Parent
Loop
parent = TryCast(child, Form)
If parent IsNot Nothing Then
parent.Close()
End If
End If
End Sub
End Class
So, as usually, there are many ways to skin a cat ;)
Re: [RESOLVED] Subclass BindingNavigator - Strange behavior
stanav, why not just do a
Code:
Dim F as form = Me.FindForm
If F isnot nothing then
F.Close()
End If
instead of looping back through the parent/child tree to find the parent form?
Re: [RESOLVED] Subclass BindingNavigator - Strange behavior
Quote:
Originally Posted by
kleinma
stanav, why not just do a
Code:
Dim F as form = Me.FindForm
If F isnot nothing then
F.Close()
End If
instead of looping back through the parent/child tree to find the parent form?
Good suggestion, Kleinma :thumb:
Didn't think of that... I need some coffee :)