none
VB.Net 2012 CollectionForm Add/Remove Buttons RRS feed

  • Question

  • I have subclassed the CollectionEditor to gain access to the CollectionForm and want to be able to know when the Add or Remove button has been clicked. Here's my subclass:

        Imports System.ComponentModel.Design

        Public Class MyCollectionEditor
            Inherits CollectionEditor


            Public Shared bEditingCollection As Boolean = False

            Public Delegate Sub MyFormClosedEventHandler(
                ByVal sender As Object,
                ByVal e As FormClosedEventArgs)

            Public Event MyFormClosed As MyFormClosedEventHandler

            Public Delegate Sub MyFormLoadEventHandler(
                ByVal sender As Object,
                ByVal e As System.EventArgs)

            Public Event MyFormLoad As MyFormLoadEventHandler

            Public Sub New(ByVal type As Type)
                MyBase.New(type)
            End Sub

            Protected Overrides Function CreateCollectionForm() As CollectionForm
                Dim collectionForm As CollectionForm = MyBase.CreateCollectionForm

                AddHandler collectionForm.FormClosed, AddressOf Me.collection_FormClosed
                AddHandler collectionForm.Load, AddressOf Me.collection_FormLoad

                Return collectionForm
            End Function

            Private Sub collection_FormLoad(ByVal sender As Object, ByVal e As System.EventArgs)
                bEditingCollection = True
            End Sub

            Private Sub collection_FormClosed(ByVal sender As Object, ByVal e As FormClosedEventArgs)
                bEditingCollection = False
            End Sub
        End Class


    Tim


    • Edited by Tim8w Thursday, September 6, 2018 3:44 PM
    Thursday, September 6, 2018 3:41 PM

Answers

  • Hi Tim,

    To figure this out you can create some temporary code that lets you examine the layout of the CollectionForm object.  Here's an example...

    First I added a temporary method to the custom editor that would give me access to the editor form:

        Public Function GetCollectionForm() As Form
            Return CreateCollectionForm()
        End Function
    

    Then I created a test form with a treeview and used the following code to load the control structure of the collection form into something I could analyze:

    Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
        Dim ce As New MyCollectionEditor(GetType(List(Of String)))
    
        Dim f = ce.GetCollectionForm
    
        Dim makeNode As Action(Of Control, TreeNode) =
            Sub(controls As Control, node As TreeNode)
                For Each c As Control In controls.Controls
                    Dim subnode = node.Nodes.Add($"{c.Name}[{c.GetType.Name}]")
                    makeNode.Invoke(c, subnode)
                Next
            End Sub
    
        Dim rootNode = TreeView1.Nodes.Add(f.Name)
        makeNode(f, rootNode)
    End Sub
    

    This revealed the control structure of the form:

    With that, it was then a simple matter of adjusting the custom editor code to add handlers to the click events of the buttons:

    Protected Overrides Function CreateCollectionForm() As CollectionForm
        Dim collectionForm As CollectionForm = MyBase.CreateCollectionForm
    
        AddHandler collectionForm.FormClosed, AddressOf Me.collection_FormClosed
        AddHandler collectionForm.Load, AddressOf Me.collection_FormLoad
        Dim panel = collectionForm.Controls.Item("overArchingTableLayoutPanel").Controls.Item("addRemoveTableLayoutPanel")
        AddHandler panel.Controls.Item("addButton").Click, AddressOf AddButton_Click
        AddHandler panel.Controls.Item("removeButton").Click, AddressOf RemoveButton_Click
    
        Return collectionForm
    End Function
    
    Private Sub AddButton_Click(sender As Object, e As EventArgs)
        MessageBox.Show("Add Button Clicked")
    End Sub
    
    Private Sub RemoveButton_Click(sender As Object, e As EventArgs)
        MessageBox.Show("Remove Button Clicked")
    End Sub
    
    So if you modify your custom editor with the above code you will get a messagebox whenever the add or remove buttons are clicked in the editor form.  You can then remove the message box code and replace it with whatever functionality you desired.


    Reed Kimble - "When you do things right, people won't be sure you've done anything at all"

    • Marked as answer by Tim8w Monday, September 10, 2018 3:25 PM
    Friday, September 7, 2018 2:45 PM
    Moderator

All replies

  • Hi Tim,

    To figure this out you can create some temporary code that lets you examine the layout of the CollectionForm object.  Here's an example...

    First I added a temporary method to the custom editor that would give me access to the editor form:

        Public Function GetCollectionForm() As Form
            Return CreateCollectionForm()
        End Function
    

    Then I created a test form with a treeview and used the following code to load the control structure of the collection form into something I could analyze:

    Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
        Dim ce As New MyCollectionEditor(GetType(List(Of String)))
    
        Dim f = ce.GetCollectionForm
    
        Dim makeNode As Action(Of Control, TreeNode) =
            Sub(controls As Control, node As TreeNode)
                For Each c As Control In controls.Controls
                    Dim subnode = node.Nodes.Add($"{c.Name}[{c.GetType.Name}]")
                    makeNode.Invoke(c, subnode)
                Next
            End Sub
    
        Dim rootNode = TreeView1.Nodes.Add(f.Name)
        makeNode(f, rootNode)
    End Sub
    

    This revealed the control structure of the form:

    With that, it was then a simple matter of adjusting the custom editor code to add handlers to the click events of the buttons:

    Protected Overrides Function CreateCollectionForm() As CollectionForm
        Dim collectionForm As CollectionForm = MyBase.CreateCollectionForm
    
        AddHandler collectionForm.FormClosed, AddressOf Me.collection_FormClosed
        AddHandler collectionForm.Load, AddressOf Me.collection_FormLoad
        Dim panel = collectionForm.Controls.Item("overArchingTableLayoutPanel").Controls.Item("addRemoveTableLayoutPanel")
        AddHandler panel.Controls.Item("addButton").Click, AddressOf AddButton_Click
        AddHandler panel.Controls.Item("removeButton").Click, AddressOf RemoveButton_Click
    
        Return collectionForm
    End Function
    
    Private Sub AddButton_Click(sender As Object, e As EventArgs)
        MessageBox.Show("Add Button Clicked")
    End Sub
    
    Private Sub RemoveButton_Click(sender As Object, e As EventArgs)
        MessageBox.Show("Remove Button Clicked")
    End Sub
    
    So if you modify your custom editor with the above code you will get a messagebox whenever the add or remove buttons are clicked in the editor form.  You can then remove the message box code and replace it with whatever functionality you desired.


    Reed Kimble - "When you do things right, people won't be sure you've done anything at all"

    • Marked as answer by Tim8w Monday, September 10, 2018 3:25 PM
    Friday, September 7, 2018 2:45 PM
    Moderator
  • Reed,

    That got me what I needed to a point. I tried adding handlers for Validating for Add/Remove/Up/Down, but the results were not consistent. Sometimes Validating got called, sometimes not. Sometimes the Validating for the Add was call when the Remove was clicked. Is it not really supported in this case?

    Thanks,

    Tim


    Tim

    Monday, September 10, 2018 9:08 PM
  • Validating wouldn't be the right event for a button... there's nothing to validate.  Use the Click event.

    Note that the Up/Down buttons are in a different container control than the Add/Remove buttons.


    Reed Kimble - "When you do things right, people won't be sure you've done anything at all"

    Tuesday, September 11, 2018 10:20 AM
    Moderator
  • Reed,

    Click is fine, except that I don't have access to cancel the click. I need to either stop the click before it happens or have the ability to revert the results of the click, like with e.Cancel or something similar.

    I can see two other option possibilities. One would simply be to save the state of the Collection before entering and restore it after. The second would be to disable the Add/Remove/Up/Down buttons. Are either of these doable?


    Tim



    • Edited by Tim8w Tuesday, September 11, 2018 6:00 PM
    Tuesday, September 11, 2018 2:10 PM
  • Well, those buttons are just controls on a form so if you set their Visibility or Enabled to False, that should make them disappear or be disabled.



    Reed Kimble - "When you do things right, people won't be sure you've done anything at all"

    Tuesday, September 11, 2018 3:10 PM
    Moderator
  • Reed,

    I tried the following:

        Private Sub collection_FormLoad(ByVal sender As Object, ByVal e As System.EventArgs)
            Dim colForm As CollectionEditor.CollectionForm = DirectCast(sender,CollectionEditor.CollectionForm)
    
            colForm.Controls.Item("overArchingTableLayoutPanel").Controls.Item("addRemoveTableLayoutPanel").Controls.Item("addButton").Enabled = False
            colForm.Controls.Item("overArchingTableLayoutPanel").Controls.Item("addRemoveTableLayoutPanel").Controls.Item("removeButton").Enabled = False
            colForm.Controls.Item("overArchingTableLayoutPanel").Controls.Item("upButton").Enabled = False
            colForm.Controls.Item("overArchingTableLayoutPanel").Controls.Item("downButton").Enabled = False
        End Sub
    But, all the buttons still function. Am I doing this wrong?


    Tim

    Tuesday, September 11, 2018 3:45 PM
  • Reed,

    'Enabled' didn't work as I mentioned above, but 'Visible' worked. I can live with that just fine. Again, thanks for all your help!


    Tim

    Tuesday, September 11, 2018 5:33 PM