none
VB.NET - Thousands of code lines for a single form. RRS feed

  • Question

  • Hi, 

    I'm developing a big application with a lot of features and the number of lines of my code, just for a single form (Form1) is over 5000 (and i've to implement other features yet). The application works very well but I'd like to know if there is a problem in having so many lines in a single form. 

    Thank you. 


    • Edited by Time90 Monday, June 19, 2017 6:31 PM
    Monday, June 19, 2017 6:31 PM

All replies

  • Couple things come to mind, first and foremost is maintainability. Just last year I was loaned out to a sister company where the developer there had about 5,000 lines of code in a single form. I spent a better part of the day figuring out code flow (if there was any, not really). Once jumping into said code I found many issues because of the code flow including the use of private variable which 99% of them would be better done localized. This also caused bugs and really difficult to debug.

    It's better to consolidate functionality outside the form by using small classes when humanly possible detaching from the actual controls on the form.

    Bottom line, even a very complex form should not have more than say 300 line of code and that is pushing it as this would include comments. One should consider refactoring as my bet is (with no disrespect) you have code that could be refactored as most developers will repeat code that could be compartmentalized but never do so. 

    If the form becomes corrupt, there are many lines of code which needs to be extracted while with dividing code into classes as mentioned above less lines of code need to be extracted.

    Consider learning the Gang of Four (GoF) which I believe there are 23 patterns.


    Please remember to mark the replies as answers if they help and unmark them if they provide no help, this will help others who are looking for solutions to the same or similar problem. Contact via my Twitter (Karen Payne) or Facebook (Karen Payne) via my MSDN profile but will not answer coding question on either.
    VB Forums - moderator
    profile for Karen Payne on Stack Exchange, a network of free, community-driven Q&A sites

    • Proposed as answer by Cor Ligthert Monday, June 19, 2017 8:11 PM
    Monday, June 19, 2017 6:52 PM
    Moderator
  • 5,000 lines in a single form?  Readability and maintainability can be nothing but a nightmare for anyone the has to deal with the code after you.

    https://en.wikipedia.org/wiki/Separation_of_concerns

    https://www.codeproject.com/Articles/228214/Understanding-Basics-of-UI-Design-Pattern-MVC-MVP

    https://msdn.microsoft.com/en-us/library/bb384398.aspx

    https://www.codeproject.com/Articles/21115/Building-an-N-Tier-Application-in-VB-NET-in-Step

    http://www.dofactory.com/products/net-design-pattern-framework

    A pity that that spam for dotfactory is again in this thread, general idea I would have proposed as answer. 

    Success
    Cor

    Monday, June 19, 2017 8:13 PM
  • 5,000 lines in a single form?  Readability and maintainability can be nothing but a nightmare for anyone the has to deal with the code after you.

    https://en.wikipedia.org/wiki/Separation_of_concerns

    https://www.codeproject.com/Articles/228214/Understanding-Basics-of-UI-Design-Pattern-MVC-MVP

    https://msdn.microsoft.com/en-us/library/bb384398.aspx

    https://www.codeproject.com/Articles/21115/Building-an-N-Tier-Application-in-VB-NET-in-Step

    http://www.dofactory.com/products/net-design-pattern-framework

    A pity that that spam for dotfactory is again in this thread, general idea I would have proposed as answer. 

    Success
    Cor


    It's a pity it's over your head. You got nothing else to do but harass people, huh? It was just a matter of time before you came of your crow's fence and showed.
    Monday, June 19, 2017 8:31 PM
  • Very clear. 

    Actually I'm not a developer, but i'm creating this application for an internal use. 

    Anyway, just to have an idea, let's consider i've an event in the form1 that is like this (click event on the cell of the datagridview): 

    Private Sub DataGridView1_CellClick(sender As Object, e As DataGridViewCellEventArgs) Handles DataGridView1.CellClick
    Dim i As Integer
            i = datagridview1.CurrentRow.Index
     
    If String.IsNullOrEmpty(CStr(Me.datagridview1.Item(0, i).Value.ToString)) And String.IsNullOrEmpty(CStr(Me.datagridview1.Item(1, i).Value.ToString)) And String.IsNullOrEmpty(CStr(Me.datagridview1.Item(2, i).Value.ToString)) Then
                txt1.Text = "unknown"
            ElseIf String.IsNullOrEmpty(CStr(Me.datagridview1.Item(0, i).Value.ToString)) Then
                txt1.Text = datagridview1.Item(1, i).Value & " " & datagridview1.Item(2, i).Value
            Else
                txt1.Text = datagridview1.Item(0, i).Value & " " & datagridview1.Item(1, i).Value & " " & datagridview1.Item(2, i).Value
            End If
    
    End Sub


    Now consider that I've 200 textboxes to manage in this way (from txt1 to txt200 ). How can i create an external class for this kind of operation? Because if i put all the code for all the 200 textboxes, this event will be 700 lines long!!

    I mean in the class do i have to import 200 textboxes? 

    Thank you very much.







    • Edited by Time90 Monday, June 19, 2017 8:53 PM
    Monday, June 19, 2017 8:40 PM
  • Time,

    The first question you should ask is how do I get rid of 199 text boxes on my form?

    :)


    Monday, June 19, 2017 8:52 PM
  • The problem is that i need all that text boxes, because they are values extracted from a database and all of them are needed in the form.
    Monday, June 19, 2017 8:56 PM
  • The problem is that i need all that text boxes, because they are values extracted from a database and all of them are needed in the form.

    Look for a better control at least.

    Describe what you are doing. Show a pic if you can or link to something similar. Describe the data. What is being entered by the user that requires 200 text boxes to do it? That's what textboxes are for, entering a value.

    Monday, June 19, 2017 9:00 PM
  • Now consider that I've 200 textboxes to manage in this way (from txt1 to txt200 ). How can i create an external class for this kind of operation? Because if i put all the code for all the 200 textboxes, this event will be 700 lines long

    This is where something like Model View Presenter could come into play. It's a UI design pattern  that implements Separation of Concerns or  Separation of Duties where the code that controls the control, validation, etc, ect is segregated/moved to the Presenter.

    The UI only has the 200 textboxes and control is given over to the Presenter on the control' event. There would be a like event in the Presenter and the textbox is passed on an Interface as a object  to be controlled by the Presenter.

    In affect,  the UI becomes a dumb UI with very little code at the UI. The Presenter is unit testable too.

    http://www.hackinghat.com/index.php/windows/mvp-aka-mvc-in-vbnet

    The tutorial here is not as advanced as the ones I have used or developed where control objects are being passed into the Presenter, but it is a start for you to move code out of the UI and make the UI as dumb as possible.

    Monday, June 19, 2017 9:03 PM
  • The user import data from an access database and all this data are arranged in the form (in several Tabs). 

    Then he can edit each of this data (this why textbox) and modify the database. 

    I don't want to let the user edit directly the datagridview.

    Monday, June 19, 2017 9:05 PM
  • It is a shame that you do have 200 textboxes on a form that can't be user friendly. You should think about segregating the textboxes on several forms with navigation buttons on each form to move to the previous or next form and a submit button on each form to submit the data from all the forms at anytime.
    Monday, June 19, 2017 9:12 PM
  • The user import data from an access database and all this data are arranged in the form (in several Tabs). 

    Then he can edit each of this data (this why textbox) and modify the database. 

    I don't want to let the user edit directly the datagridview.

    Well then I think you need a class maybe for each tab??? Or the data you read for the 200 text boxes. The form would just call the class, like a DGV but the class code is in a separate code module.

    You can make a list of 200 text boxes using Listof (T) and then easily loop the 200 instead of repeating the same code 200 times.

    So there are lots of ways.

    Is this the basic thing you do?

    1. Read 200 values from a database.

    2. Put 200 values in the DGV.

    3. Repeat the same 200 values in 200 text boxes.

    4. User enters 200 changes? Or user changes some of the 200 values?

    5. User clicks SAVE and you move the entries from the textboxes to the DB?

    • Proposed as answer by Cor Ligthert Tuesday, June 20, 2017 8:59 AM
    Monday, June 19, 2017 9:16 PM
  • Actually they are not 200 text boxes, maybe 40. 200 was an example for the previous question. Anyway the code i wrote before, applied to 40 text boxes is long 600-700 lines

    Monday, June 19, 2017 9:16 PM
  • The user import data from an access database and all this data are arranged in the form (in several Tabs). 

    Then he can edit each of this data (this why textbox) and modify the database. 

    I don't want to let the user edit directly the datagridview.

    Well then I think you need a class maybe for each tab??? Or the data you read for the 200 text boxes. The form would just call the class, like a DGV but the class code is in a separate code module.

    You can make a list of 200 text boxes using Listof (T) and then easily loop the 200 instead of repeating the same code 200 times.

    So there are lots of ways.

    Is this the basic thing you do?

    1. Read 200 values from a database.

    2. Put 200 values in the DGV.

    3. Repeat the same 200 values in 200 text boxes.

    4. User enters 200 changes? Or user changes some of the 200 values?

    5. User clicks SAVE and you move the entries from the textboxes to the DB?

    Exactly. But is better if the user can edit every text boxes directly, without opening a different form. This was a specific request of the user that will use this application.

    Could you please write an example with Listof (T).

    It would be really helpful and i'll appreciate a lot :) 


    Monday, June 19, 2017 9:24 PM
  • Actually they are not 200 text boxes, maybe 40. 200 was an example for the previous question. Anyway the code i wrote before, applied to 40 text boxes is long 600-700 lines


    You would have a Presenter for each form or tab of controls. The Presenter  would have the code for that form or tab only so that class wouldn't have 700 lines of code in it, a segregation of code segregated to each form's or tab's Presenter.
    Monday, June 19, 2017 9:24 PM
  • Exactly. But is better if the user can edit every text boxes directly, without opening a different form. This was a specific request of the user that will use this application.

    Could you please write an example with Listof (T).

    It would be really helpful and i'll appreciate a lot :) 


    Ok I will look for one. Its real easy once you see it. What is your skill level? Do you know classes? We don't know what you know. :)

    Desribe what the tabs are? Is there 10 text boxes on one tab, 20 on another ... total 40 textboxes?

    Why don't you just use the DGV to edit the values instead of textboxes?

    Is the DGV bound to the database? Or how does that work?

    Monday, June 19, 2017 9:29 PM
  • The dgv is bound to the database. 
    I need to have all the values in the form organized in a specific way. The user doesn't even see the datagridview that is unvisible. I know it would have been better to let the use edit the dgv, but for some reasons (that are not important to explain now), he doesn't want to. 
    The number of txt in the tabs is more or less 30/10/10 (in three tabs).

    I've always created application with not a lot of lines of code, so i'm not really expert with classes and i'm not a programmer :) I use vb.net just to simplify my life in some operations!! So i'm really sorry for that!

    Thank you. You all are very kind :) 

    ----

    ps. Consider that the code, i would like to slim down is like this. How can i slim down this code with classes or Listof (T)?

    If condition1  Then
                txt1.Text = "text"
            ElseIf condition2 Then
                txt1.Text = datagridview1.Item(1, i).Value & " " & datagridview1.Item(2, i).Value
            Else
                txt1.Text = datagridview1.Item(0, i).Value & " " & datagridview1.Item(1, i).Value & " " & datagridview1.Item(2, i).Value
            End If








    • Edited by Time90 Monday, June 19, 2017 9:50 PM
    Monday, June 19, 2017 9:37 PM
  • Here is one way to make a list of controls.

    Of course there are many ways.

    I added an event handler for textchanged but you can do any or multiple events as reqd.

    Public Class Form2
        Private WithEvents Button1 As New Button With {.Parent = Me,
            .Location = New Point(200, 200), .Text = "Save"}
    
        Private TbList As New List(Of TextBox)
        Private MyDataList As New List(Of Integer)
    
        Private Sub Form2_Load(sender As Object, e As EventArgs) Handles Me.Load
            'read the data for one case
            For i As Integer = 10 To 15
                MyDataList.Add(i)
            Next
    
    
            'make the controls
            For i As Integer = 0 To MyDataList.Count - 1
                Dim newTb As New TextBox
                With newTb
                    .Name = "Textbox " & i.ToString
                    .Location = New Point(30, 20 + i * 40)
                    .Text = CStr(MyDataList(i))
                    Me.Controls.Add(newTb)
                    AddHandler .TextChanged, AddressOf MyTextBoxes_TextChanged
                End With
            Next
        End Sub
        Private Sub MyTextBoxes_TextChanged(ByVal obj As Object, ByVal e As EventArgs)
            'make any required ??
    
        End Sub
    
        Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
            'save the new data back to the list
            For i As Integer = 0 To TbList.Count - 1
                If IsNumeric(TbList(i).Text) Then
                    MyDataList(i) = CInt(TbList(i).Text)
                End If
            Next
    
            MsgBox(String.Join(",", MyDataList.ToArray()))
    
        End Sub
    End Class
    
    
    



    Monday, June 19, 2017 10:00 PM
  • The dgv is bound to the database. 
    I need to have all the values in the form organized in a specific way. The user doesn't even see the datagridview that is unvisible. I know it would have been better to let the use edit the dgv, but for some reasons (that are not important to explain now), he doesn't want to. 
    The number of txt in the tabs is more or less 30/10/10 (in three tabs).

    I've always created application with not a lot of lines of code, so i'm not really expert with classes and i'm not a programmer :) I use vb.net just to simplify my life in some operations!! So i'm really sorry for that!

    Thank you. You all are very kind :) 

    ----

    ps. Consider that the code, i would like to slim down is like this. How can i slim down this code with classes or Listof (T)?

    If condition1  Then
                txt1.Text = "text"
            ElseIf condition2 Then
                txt1.Text = datagridview1.Item(1, i).Value & " " & datagridview1.Item(2, i).Value
            Else
                txt1.Text = datagridview1.Item(0, i).Value & " " & datagridview1.Item(1, i).Value & " " & datagridview1.Item(2, i).Value
            End If








    Well seems to me if the user does not see the DGV it is not required? You should use the database.

    Or another table maybe. But you should not use a DGV just to store data.

    Look at the control list example I just posted and see if it makes sense.

    As I say there are many ways. I am sure now others can make suggestions too.

    BTW please be specific whom/which post you are responding to etc as reqd.

    Monday, June 19, 2017 10:06 PM
  • Consider that the code, i would like to slim down is like this. How can i slim down this code with classes or Listof (T)?

    For that sort of code you don't need a list, although it might be useful for setting up the event handlers in the first place.

    If you re-arrange the event handlers so that all text boxes are handled in one event, then you replace 'txt1' with a reference to a textbox object created from the sender argument provided to the method.

        Private Sub TextBox1_TextChanged(sender As Object, e As EventArgs) Handles 
            txt1.TextChanged, _
            txt2.TextChanged, _
            txt3.TextChanged, _
            txt4.TextChanged)
            '...
            Dim ThisTxt As TextBox = CType(sender, TextBox)
            If condition1 Then
                ThisTxt.Text = "text"
            ElseIf condition2 Then
                ThisTxt.Text = datagridview1.Item(1, i).Value & " " & datagridview1.Item(2, i).Value
            Else
                ThisTxt.Text = datagridview1.Item(0, i).Value & " " & datagridview1.Item(1, i).Value & " " & datagridview1.Item(2, i).Value
            End If
        End Sub
    

    If the 'text' varies then you can use the Tag property of the text box (set up at program initialisation) instead of the literal.

    If the DGV is invisible then you should be able to get significant code savings by replacing it with an alternative data store, such as a datatable or a simple list of class instances.

    Monday, June 19, 2017 10:16 PM
  • In regards to 200 TextBox controls (I'm guess a Label for each) you could place most of the code into a class, place the controls onto a TableLayoutPanel with the rows/columns configured at runtime.

    In the following example (took about an hour) I dynamically place both labels and textbox controls onto a TableLayoutPanel and data bind to the TextBoxes. Granted this is a very simple example that is not full featured but it gets the point across we can minimize code in the form.

    This class does 99 percent of the work.

    Imports System.IO
    
    Public Class TableLayoutDataAccess
        Private Builder As OleDbConnectionStringBuilder =
            New OleDbConnectionStringBuilder() With
                {
                    .Provider = "Microsoft.ACE.OLEDB.12.0",
                    .DataSource = Path.Combine(Application.StartupPath, "Database1.accdb")
                }
    
        Private mSelectStatement As String = ""
        Public ReadOnly Property SelectCustomersStatement As String
            Get
                Return mSelectStatement
            End Get
        End Property
        Public ReadOnly Property Id As String = "Identifier"
    
        Public Function GetItems() As List(Of LabelTextBox)
            Dim theList As New List(Of LabelTextBox)
            Dim colNames As List(Of String) = ColumnNames()
    
            For Each col As String In colNames
    
                theList.Add(New LabelTextBox With
                    {
                        .DataMember = col,
                        .LabelName = AddSpacesToSentence(col, True),
                        .TextBoxName = $"tb{col}"
                    })
            Next
    
            mSelectStatement = $"SELECT {String.Join(",", colNames.ToArray)} FROM Customers"
    
            Return theList
        End Function
        Public Function GetData() As DataTable
            Dim dt As New DataTable
            Using cn As New OleDbConnection With {.ConnectionString = Builder.ConnectionString}
                Using cmd As New OleDbCommand With {.Connection = cn, .CommandText = mSelectStatement}
                    cn.Open()
                    dt.Load(cmd.ExecuteReader)
                End Using
            End Using
            Return dt
        End Function
        Public Function ColumnNames() As List(Of String)
    
            Using cn As New OleDbConnection() With {.ConnectionString = Builder.ConnectionString}
                cn.Open()
                Return GetColumns(cn, "Customers")
            End Using
    
        End Function
        Private Function GetColumns(ByVal connection As OleDbConnection, ByVal tableName As String) As List(Of String)
    
            Dim columns As New List(Of String)()
            Dim columnsTable As DataTable = connection _
                .GetSchema("Columns", New String() {Nothing, Nothing, tableName, Nothing})
    
            Dim results = columnsTable.AsEnumerable() _
                .OrderBy(Function(c) c.Field(Of Int64)("ORDINAL_POSITION")).ToList()
    
            For Each item In results
                columns.Add(item.Field(Of String)("COLUMN_NAME"))
            Next
    
            Return columns
    
        End Function
    
    End Class
    Public Class LabelTextBox
        Public Property LabelName As String
        Public Property TextBoxName As String
        Public Property DataMember As String
    End Class

    Utility code to split field names, used above (I could had made this a language extension method but dinner is calling)

    Imports System.Text
    
    Public Module StringHelpers
        Public Function AddSpacesToSentence(ByVal text As String, ByVal preserveAcronyms As Boolean) As String
            If String.IsNullOrWhiteSpace(text) Then
                Return String.Empty
            End If
    
            Dim sb As New StringBuilder(text.Length * 2)
            sb.Append(text.Chars(0))
    
            For i As Integer = 1 To text.Length - 1
                If Char.IsUpper(text.Chars(i)) Then
                    If (text.Chars(i - 1) <> " "c AndAlso (Not Char.IsUpper(text.Chars(i - 1)))) OrElse (preserveAcronyms AndAlso Char.IsUpper(text.Chars(i - 1)) AndAlso i < text.Length - 1 AndAlso (Not Char.IsUpper(text.Chars(i + 1)))) Then
                        sb.Append(" "c)
                    End If
                End If
    
                sb.Append(text.Chars(i))
    
            Next
    
            Return sb.ToString()
        End Function
    End Module

    Form code

    Public Class Form5
        Private bsData As New BindingSource
    
        Private Sub Form5_Load(sender As Object, e As EventArgs) Handles MyBase.Load
            Dim ops As New TableLayoutDataAccess
            Dim ShowIt As Boolean = True
            Dim tb As New TextBox
    
            Dim items = ops.GetItems()
            bsData.DataSource = ops.GetData
            TableLayoutPanel1.RowCount = ops.ColumnNames.Count
    
            For Each item In items
                If item.DataMember = ops.Id Then
                    ShowIt = False
                Else
                    ShowIt = True
                End If
                TableLayoutPanel1.Controls.Add(New Label With
                {
                    .Text = item.LabelName,
                    .Name = item.TextBoxName,
                    .Margin = New Padding() With {.All = 4},
                    .Visible = ShowIt
                })
    
                tb = New TextBox With
                {
                    .Name = item.TextBoxName,
                    .Margin = New Padding() With {.All = 4},
                    .Visible = ShowIt
                }
    
                tb.DataBindings.Add("Text", bsData, item.DataMember)
                TableLayoutPanel1.Controls.Add(tb)
                TableLayoutPanel1.RowStyles.Add(New RowStyle)
            Next
    
            Dim styles As TableLayoutRowStyleCollection = TableLayoutPanel1.RowStyles
            For Each style As RowStyle In styles
                style.SizeType = SizeType.Absolute
                style.Height = 20
            Next
    
            BindingNavigator1.BindingSource = bsData
        End Sub
    End Class


    In this example I hide the id field. If there are more fields then this you might do tabs or if not many more fields we can configure for scrolling e.g.

    Again, this is a simple example to get a point across.

    EDIT: Here is a modified version of the form code where I show how to setup a Click event that shows information about the data which in a real app would do something rather than show a message.

    Public Class Form5
        Private bsData As New BindingSource
    
        Private Sub Form5_Load(sender As Object, e As EventArgs) Handles MyBase.Load
            Dim ops As New TableLayoutDataAccess
            Dim ShowIt As Boolean = True
            Dim tb As New TextBox
    
            Dim items = ops.GetItems()
            bsData.DataSource = ops.GetData
            TableLayoutPanel1.RowCount = ops.ColumnNames.Count
    
            For Each item In items
                If item.DataMember = ops.Id Then
                    ShowIt = False
                Else
                    ShowIt = True
                End If
                TableLayoutPanel1.Controls.Add(New Label With
                {
                    .Text = item.LabelName,
                    .Name = item.TextBoxName,
                    .Margin = New Padding() With {.All = 4},
                    .Visible = ShowIt
                })
    
                tb = New TextBox With
                {
                    .Name = item.TextBoxName,
                    .Margin = New Padding() With {.All = 4},
                    .Visible = ShowIt,
                    .Tag = item
                }
    
                tb.DataBindings.Add("Text", bsData, item.DataMember)
                TableLayoutPanel1.Controls.Add(tb)
                TableLayoutPanel1.RowStyles.Add(New RowStyle)
            Next
    
            TableLayoutPanel1.Controls.OfType(Of TextBox) _
                .ToList.ForEach(Sub(tBox)
                                    AddHandler tBox.Click,
                                        Sub(s As Object, a As EventArgs)
                                            MessageBox.Show(CType(CType(s, TextBox).Tag, LabelTextBox).DataMember)
                                        End Sub
    
                                End Sub)
    
    
            Dim styles As TableLayoutRowStyleCollection = TableLayoutPanel1.RowStyles
            For Each style As RowStyle In styles
                style.SizeType = SizeType.Absolute
                style.Height = 20
            Next
    
            BindingNavigator1.BindingSource = bsData
        End Sub
    
        Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
            Simple()
        End Sub
    End Class

    With that you could event have a custom TextBox

    Public Class KarenTextBox
        Inherits TextBox
        Public Property LabelTextBox As LabelTextBox
    End Class
    

    Modified form code

    Public Class Form5
        Private bsData As New BindingSource
    
        Private Sub Form5_Load(sender As Object, e As EventArgs) Handles MyBase.Load
            Dim ops As New TableLayoutDataAccess
            Dim ShowIt As Boolean = True
            Dim tb As New TextBox
    
            Dim items = ops.GetItems()
            bsData.DataSource = ops.GetData
            TableLayoutPanel1.RowCount = ops.ColumnNames.Count
    
            For Each item In items
                If item.DataMember = ops.Id Then
                    ShowIt = False
                Else
                    ShowIt = True
                End If
                TableLayoutPanel1.Controls.Add(New Label With
                {
                    .Text = item.LabelName,
                    .Name = item.TextBoxName,
                    .Margin = New Padding() With {.All = 4},
                    .Visible = ShowIt
                })
    
                tb = New KarenTextBox With
                {
                    .Name = item.TextBoxName,
                    .Margin = New Padding() With {.All = 4},
                    .Visible = ShowIt,
                    .LabelTextBox = item
                }
    
                tb.DataBindings.Add("Text", bsData, item.DataMember)
                TableLayoutPanel1.Controls.Add(tb)
                TableLayoutPanel1.RowStyles.Add(New RowStyle)
            Next
    
            TableLayoutPanel1.Controls.OfType(Of KarenTextBox) _
                .ToList.ForEach(Sub(tBox)
                                    AddHandler tBox.Click,
                                        Sub(s As Object, a As EventArgs)
                                            MessageBox.Show(CType(s, KarenTextBox).LabelTextBox.DataMember)
                                        End Sub
    
                                End Sub)
    
    
            Dim styles As TableLayoutRowStyleCollection = TableLayoutPanel1.RowStyles
            For Each style As RowStyle In styles
                style.SizeType = SizeType.Absolute
                style.Height = 20
            Next
    
            BindingNavigator1.BindingSource = bsData
        End Sub
    
        Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
            Simple()
        End Sub
    End Class


    Please remember to mark the replies as answers if they help and unmark them if they provide no help, this will help others who are looking for solutions to the same or similar problem. Contact via my Twitter (Karen Payne) or Facebook (Karen Payne) via my MSDN profile but will not answer coding question on either.
    VB Forums - moderator
    profile for Karen Payne on Stack Exchange, a network of free, community-driven Q&A sites


    Monday, June 19, 2017 11:35 PM
    Moderator
  • The user doesn't even see the datagridview that is unvisible. I know it would have been better to let the use edit the dgv, 

    Then we have your first problem. The DataGridView is only a presentation part. Therefore in the way you write it, you should (must) not use it. It only creates very much weak (not stable) code.

    You wrote, you are not a developer, therefore I understand you try to use a kind of spreadsheet solution. However, that is made for end users. Behind the scene are more than those 5000 lines of your code. Not to make it robust, but as a translation between computer and end user on a very basal level. 

    This does maybe help you but not to what is the solution. Therefore tell us what kind of database you use. That can even be excel but I doubt it. Depending on that we can give you solutions because in .Net there are some standardised ways to handle this but depending from the used database.

    You see you get a mass of replies. But I miss at least the base on what that is given. 

    Be aware, the 200 textboxes are not the problem at all, in a real business application with tabpages it is not extraordinary (but it is much). 


    Success
    Cor



    Tuesday, June 20, 2017 9:08 AM
  • Time90,

    I'm curious: What does your program do?


    "A problem well stated is a problem half solved.” - Charles F. Kettering

    Tuesday, June 20, 2017 11:57 AM
  • In regards to 200 TextBox controls (I'm guess a Label for each) you could place most of the code into a class, place the controls onto a TableLayoutPanel with the rows/columns configured at runtime.

    In the following example (took about an hour) I dynamically place both labels and textbox controls onto a TableLayoutPanel and data bind to the TextBoxes. Granted this is a very simple example that is not full featured but it gets the point across we can minimize code in the form.

    (...)

    profile for Karen Payne on Stack Exchange, a network of free, community-driven Q&A sites

    Karen i really appreciated your contribute. very very helpful. I tried to use a system like this in the past (now is really more clear) but for this application I can't use another panel to edit the rows of the datagridview. It must be done within the same form, editing the text boxes and then clicking on a button "EDIT". I know it could appear weird, but there are some reasonable reasons. 

    Let's make simple the problem: 

    I have 50 text boxes in a form. 

    The user click on a row of a datagridview (in the dgv is visible just the first column) and the clicking event changes the contents of the 50 txt (with the contents of the dgv cells). 

    At this point the user can edit the txt he wants, and click on save to introduce the change in the database. 

    The click event in my code is long 700 lines because of the number of cells in a single row and for each I've to use a condition (if then else), like in the code posted before.

    So if it's possible to put all this code  in a class  and recall it from the form it would be very useful, but the problem is that I've to declare 50 variables in the class and then populate the class from the form if I'm not wrong. 

    Is it possible to take some instruction and put them outside the form and then recall in some way? I was thinking to create modules.

    I'm sorry if my requests are not interesting. I hope everything is clear and sorry for my english. 

    Thank you :) 





    • Edited by Time90 Tuesday, June 20, 2017 12:34 PM
    Tuesday, June 20, 2017 12:18 PM
  • Here is one way to make a list of controls.

    Of course there are many ways.

    I added an event handler for textchanged but you can do any or multiple events as reqd.

    Public Class Form2
        Private WithEvents Button1 As New Button With {.Parent = Me,
            .Location = New Point(200, 200), .Text = "Save"}
    
        Private TbList As New List(Of TextBox)
        Private MyDataList As New List(Of Integer)
    
        Private Sub Form2_Load(sender As Object, e As EventArgs) Handles Me.Load
            'read the data for one case
            For i As Integer = 10 To 15
                MyDataList.Add(i)
            Next
    
    
            'make the controls
            For i As Integer = 0 To MyDataList.Count - 1
                Dim newTb As New TextBox
                With newTb
                    .Name = "Textbox " & i.ToString
                    .Location = New Point(30, 20 + i * 40)
                    .Text = CStr(MyDataList(i))
                    Me.Controls.Add(newTb)
                    AddHandler .TextChanged, AddressOf MyTextBoxes_TextChanged
                End With
            Next
        End Sub
        Private Sub MyTextBoxes_TextChanged(ByVal obj As Object, ByVal e As EventArgs)
            'make any required ??
    
        End Sub
    
        Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
            'save the new data back to the list
            For i As Integer = 0 To TbList.Count - 1
                If IsNumeric(TbList(i).Text) Then
                    MyDataList(i) = CInt(TbList(i).Text)
                End If
            Next
    
            MsgBox(String.Join(",", MyDataList.ToArray()))
    
        End Sub
    End Class
    
    



    Thank you very interesting solution. I will look at this today.
    Tuesday, June 20, 2017 12:19 PM
  • Thank you very interesting solution. I will look at this today.

    You are welcome.

    In case you did not notice, you can insert the code Acamar shows into the event handler we make in form load. Then, instead of declaring the textboxes in the event code like Acamar shows, since we did it in the form load already we can leave the textbox1, textbox2... out like shown below.

    So the user clicks the line in the dgv that will be edited and you either make a datatable or a list of the data for that row as I did with my loop to make the MyDataList list as I did in the example in the start of form load. You can do this anyway that works with your database etc. Does not have to be a list, could be a datatable and etc.

    I used integers for my data you will have to change to string or whatever you need.

        Private Sub MyTextBoxes_TextChanged(ByVal sender As Object, ByVal e As EventArgs)
    
            Dim ThisTxt As TextBox = CType(sender, TextBox)
    
            If condition1 Then
                ThisTxt.Text = "text"
            ElseIf condition2 Then
                ThisTxt.Text = datagridview1.Item(1, i).Value & " " & datagridview1.Item(2, i).Value
            Else
                ThisTxt.Text = datagridview1.Item(0, i).Value & " " & datagridview1.Item(1, i).Value & " " & datagridview1.Item(2, i).Value
            End If
    
    
        End Sub


    PS if you make a class with all your data declared in the class and a subroutine in the class to fill the class variables and put them into the textboxes you can use the class instead of a list or new datatable of the current datarow.

    But first try the example as is and then when that is clear to you, you can either move on or learn to make a class to hold the data and perform some functions.

    Tuesday, June 20, 2017 12:35 PM
  • for a single form (Form1) is over 5000 (and i've to implement other features yet). The application works very well but I'd like to know if there is a problem in having so many lines in a single form. 

    Thank you. 


    Hi

    5000 lines is not a problem at all. That's small. Obviously you have partitioned and structured your code in a way that's relevant to you.

    I have found with VS2015, the editor starts to become slow and halting when you have subs larger than 3000 lines (with cutting, deletions, insertions etc). I always have the rest of the subs minimized (unexpanded), and only have a few relevant subs expanded in the editor whilst coding. 


    Pride is the most destructive force in the universe

    Wednesday, June 21, 2017 12:07 AM
  • for a single form (Form1) is over 5000 (and i've to implement other features yet). The application works very well but I'd like to know if there is a problem in having so many lines in a single form. 

    Thank you. 


    Hi

    5000 lines is not a problem at all. That's small. Obviously you have partitioned and structured your code in a way that's relevant to you.

    I have found with VS2015, the editor starts to become slow and halting when you have subs larger than 3000 lines (with cutting, deletions, insertions etc). I always have the rest of the subs minimized (unexpanded), and only have a few relevant subs expanded in the editor whilst coding. 


    Pride is the most destructive force in the universe

    Good point Leon.

    Now that I actually looked my no 1 has 15,000 lines in the main form and works fine.

    Wednesday, June 21, 2017 12:19 AM
  • Thanks Tommy

    Same here -  about 15000 lines. But I am continually evolving and changing the way I structure my code (as do we all). That's why I appreciate the advice of others to try and minimize sizes and follow good OOP. Sometimes in the course of one project I go back and just about re-write the whole thing.


    Pride is the most destructive force in the universe

    Wednesday, June 21, 2017 12:31 AM
  • Tommy and Leon,

    If nothing else, at least consider using Partial classes.


    "A problem well stated is a problem half solved.” - Charles F. Kettering

    Wednesday, June 21, 2017 12:45 AM