Results 1 to 7 of 7

Thread: [RESOLVED] Designerless Form Creation

  1. #1

    Thread Starter
    Fanatic Member kpmc's Avatar
    Join Date
    Sep 2017
    Posts
    1,012

    Resolved [RESOLVED] Designerless Form Creation

    For the last few weeks I have been hammering out InfoPath forms and workflows. Basically I have been living and breating all things SharePoint

    InfoPath "Code-Behind" can be unforgiving, as you would expect from working with any XML nested nightmares...

    Recently I have decided to get clever and leverage some controls out of the .Forms namespace...

    It's a bit hit and miss but I am working things out.

    Right now I am wondering why my loop in the below code wouldn't be working, I am not sure if I am initializing the controls adequately, or if maybe I should try adding the routine to an event rather than initialization.

    Also It could be fun to get a discussion going on how you would go about rendering a form if you did not have the designer and were forced to do it all in code. - I've also been wondering if maybe I could design the form in VS then copy and somehow reuse the "Form.Designer.vb"

    Anyway, the problem loop is commented with "not running" below.

    Code:
            Public Sub CTRL38_5_Clicked(ByVal sender As Object, ByVal e As ClickedEventArgs)
                Dim MachineForm As New Form
                Dim HeaderPanel As New Panel With {.Padding = New Padding(10)}
                Dim BodyPanel As New Panel With {.Padding = New Padding(10)}
                Dim FooterPanel As New Panel With {.Padding = New Padding(10)}
                Dim DGV_Machine As New DataGridView With {.DataSource = DSet.Tables("Machines")}
    
                With DGV_Machine
                    .AutoSizeColumnsMode = DataGridViewAutoSizeColumnsMode.AllCells
                    .Dock = DockStyle.Fill
              
                End With
    
                With HeaderPanel
                    .Dock = DockStyle.Top
                End With
    
                With BodyPanel
                    .Dock = DockStyle.Fill
                    .Controls.Add(DGV_Machine)
                    .BringToFront()
                End With
    
                With FooterPanel
                    .Dock = DockStyle.Bottom
                End With
    
                With MachineForm
                    .Controls.Add(FooterPanel)
                    .Controls.SetChildIndex(FooterPanel, 2)
    
                    .Controls.Add(HeaderPanel)
                    .Controls.SetChildIndex(HeaderPanel, 1)
    
                    .Controls.Add(BodyPanel)
                    .Controls.SetChildIndex(BodyPanel, 0)
    
                    Dim ColsWidth As Integer = Nothing
                    For Each Col As DataGridViewColumn In DGV_Machine.Columns 'not running
                        ColsWidth += Col.Width
                        MessageBox.Show(ColsWidth)
                    Next
                    .Width = ColsWidth
                    .Height = Screen.PrimaryScreen.Bounds.Height - 25
    
                    .StartPosition = FormStartPosition.Manual
                    .Location = New Drawing.Point(25)
    
                    .ShowDialog()
                End With
            End Sub

  2. #2
    You don't want to know.
    Join Date
    Aug 2010
    Posts
    4,578

    Re: Designerless Form Creation

    Well, the most obvious question is "Are you sure there are DataGridViewColumn items in DGV_Machine.Columns? It has a DataSource, so that means you have to answer, "Are you sure DSet.Tables("Machines") is configured enough at this point to have columns?"

    This line's a little weird and tells me you might have Option Strict Off (though I think that isn't the problem):
    Code:
    Dim ColsWidth As Integer = Nothing
    Integer cannot be assigned Nothing. But if you have Option Strict Off, VB will implicitly convert Nothing into "the default value for the type", which is 0. I think it is best to be explicit and initialize it to 0, because you mean 0.

    I did notice you don't add DGV_Machine to the form's Controls collection. But I'm assuming you commented the line you did because the MessageBox.Show() isn't executing, not because the DGV isn't on the form.

    So if I know that MessageBox.Show() isn't working, I have to ask, "When will the loop not execute its body?" It won't execute its body if there are no DataGridViewColumns to iterate. That can be true for a bunch of reasons, the most obvious being "the DataSource doesn't have any columns". But it could be "The DGV doesn't try to generate that unless it's been displayed". Who knows?

    So I think if you can, you need to set some breakpoints and poke inside those variables to make sure they look like what you expect. If you can't set breakpoints, you're going to have to write some stuff that outputs to the console or a file to tell.

    If the table's got columns, then I'm not entirely sure what's going on.
    This answer is wrong. You should be using TableAdapter and Dictionaries instead.

  3. #3

    Thread Starter
    Fanatic Member kpmc's Avatar
    Join Date
    Sep 2017
    Posts
    1,012

    Re: Designerless Form Creation

    I will have to look when I get back to the office, i generally always make sure option strict is on.

    I did notice you don't add DGV_Machine to the form's Controls collection
    I add the dgv to the panel collection, then the panel is added to the form collection
    Code:
                With BodyPanel
                    .Dock = DockStyle.Fill
                    .Controls.Add(DGV_Machine) <---
                    .BringToFront()
                End With
    I think I will try on the databindingcomplete event of the dgv and see if itll fire. there are indeed cols and rows in the dgv.

  4. #4

    Thread Starter
    Fanatic Member kpmc's Avatar
    Join Date
    Sep 2017
    Posts
    1,012

    Re: Designerless Form Creation

    Integer cannot be assigned Nothing. But if you have Option Strict Off, VB will implicitly convert Nothing into "the default value for the type", which is 0
    Option Strict was off, it actually did not cross my mind given It's not the typical IDE. I had to turn it on in code, when I did all my code lit up like a Christmas tree. Mostly all related to inferring objects into strings so I had to run through and add a bunch of ".ToString"
    It doesn't seem to mind that I am declaring/initializing an int as nothing though, nor does it mind in VS2017. I do this on nearly all declarations bcz I find it easier to test for nothing than NULL/WhiteSpace/KindaNULL/MaybeNULL/Blank

  5. #5

    Thread Starter
    Fanatic Member kpmc's Avatar
    Join Date
    Sep 2017
    Posts
    1,012

    Re: Designerless Form Creation

    This did the trick.

    Code:
    AddHandler DGV_Machine.DataBindingComplete, AddressOf DGVChange
    Code:
            Private Sub DGVChange(sender As Object, e As EventArgs)
                Dim DGV_Machine As DataGridView = CType(sender, DataGridView)
                Dim ColsWidth As Integer = Nothing
                For Each Col As DataGridViewColumn In DGV_Machine.Columns 'not running
                    ColsWidth += Col.Width
                Next
                MachineForm.Width = ColsWidth
                MachineForm.Height = Screen.PrimaryScreen.Bounds.Height - 25
            End Sub

  6. #6

    Thread Starter
    Fanatic Member kpmc's Avatar
    Join Date
    Sep 2017
    Posts
    1,012

    Re: [RESOLVED] Designerless Form Creation

    Furthermore; The controls on the form seem to be persistent whereas nothing is disposed when you close the form. I had to declare the form withevents and dispose manually.

    Code:
     WithEvents MachineForm As New Form
    Code:
            Private Sub DestoryForm(sender As Object, e As EventArgs) Handles MachineForm.FormClosed
                For Each Ctrl As Control In MachineForm.Controls
                    Ctrl.Dispose()
                Next
            End Sub

  7. #7
    You don't want to know.
    Join Date
    Aug 2010
    Posts
    4,578

    Re: [RESOLVED] Designerless Form Creation

    That's because normally the designer does that work, but you're bypassing the designer. I think it normally does a loop to dispose "all controls" but it's also true that some designer code doesn't exist until you use the designer to add something that requires it. The designer's good magic, but it's often hard to reverse-engineer just part of magic.

    RE: having to handle the event, I guess this implies something about data binding doesn't happen until the control is being displayed, so if you need to do work in response to data binding you have to handle that event to know when it's ready.
    This answer is wrong. You should be using TableAdapter and Dictionaries instead.

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  



Click Here to Expand Forum to Full Width