Want to protect your cyber security and still get fast solutions? Ask a secure question today.Go Premium

x
  • Status: Solved
  • Priority: Medium
  • Security: Public
  • Views: 3990
  • Last Modified:

Inspect / Critique 600 line VB.Net DataGridView Windows Forms application code

Hi Experts,

I've got a Windows Forms application I've pieced together over the past year or so with assistance here and other places and I think it's more like a "Franken Application" in that to solve various problems I've added code here and there that may be redundant or counter productive to itself.  My programming skills are very basic so I'm having trouble cleaning it up without breaking it.  

I'm looking for some help in looking at this thing and fixing things like filling DataTables and DataSets multiple times unnecessarily, updating an entire table where only a single record should be updated and such.

I'm using Visual Studio 2008 / VB.  The app is about 600 lines including lots of comments, many of which were authored by "TheLearnedOne" and others here who have helped me with a lot of it.

Part of what's prompting me to request help is the app updates take way longer than they should so it does not seem very responsive.

Thank you for suggestions or any help anyone could provide.  I've included various screen captures, the entire VB code and zipped up stored procedures called from the code.
Thanks in advance.
Option Strict Off
Imports System
Imports System.Data
Imports System.Data.SqlTypes
Imports System.Data.SqlClient
Imports System.Windows.Forms
Imports System.Drawing
 
Public Class YouthJob
    Private dtApplicants As DataTable
    Private cmApplicants As CurrencyManager
    Private dtJobs As DataTable
    Private dvjobs As New DataView
    Private WithEvents cmJobs As CurrencyManager
 
    Private Sub ApplicantsBindingNavigatorSaveItem_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles ApplicantsBindingNavigatorSaveItem.Click
        Me.Validate()
        Me.ApplicantsBindingSource.EndEdit()
        Me.ApplicantsTableAdapter.Update(Me.SYEP2007DataSet.Applicants)
    End Sub
 
    Private Sub YouthJob_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
        'TODO: This line of code loads data into the 'SYEP2007DataSet.JobTitles' table. You can move, or remove it, as needed.
        'Me.JobTitlesTableAdapter.Fill(Me.SYEP2007DataSet.JobTitles)
        'Me.ApplicantsTableAdapter.Fill(Me.SYEP2007DataSet.Applicants)
        Try
            Me.JobTitlesTableAdapter.Fill(Me.SYEP2007DataSet.JobTitles)
        Catch ex As Exception
            MessageBox.Show(ex.StackTrace)
        End Try
        Try
            Me.ApplicantsTableAdapter.Fill(Me.SYEP2007DataSet.Applicants)
        Catch ex As Exception
            MessageBox.Show(ex.StackTrace)
        End Try
 
        dtApplicants = Me.SYEP2007DataSet.Applicants
        dtJobs = Me.SYEP2007DataSet.JobTitles
 
        'filltables() 'equivalent to filling tables with ...
        '... a dataadapter or a tableadapter
 
        'get and display the count of applicant records
        'Dim count As Integer = dtApplicants.Rows.Count 'So I can filter the count I added a Stored Procedure and us it instead _
        '                                                 of dtApplicants.Rows.Count.
        Dim count As Integer = CType(Me.ApplicantsTableAdapter.spCount_Applicants2008Total, Integer)
        txtTotalApplicants.Text = String.Format("{0} Applicants", count)
 
        'bind the applicants table to the datagridview
        ApplicantsDataGridView.DataSource = dtApplicants
        'set up the currencymanager - convenient for referring ...
        '... to the currently selected row in the applicants grid
        cmApplicants = CType(BindingContext(dtApplicants), CurrencyManager)
 
        'set up a dataview to filter the jobs table so it ...
        '... only shows those where some jobs remain available
        dvjobs.Table = dtJobs
        'dvjobs.RowFilter = "txtWorksiteJobTitlePositionsNumber > 0"         '<<<<<Moved to end of YouthJob_Load
        'bind the jobs table to the datagridview
        JobTitlesDataGridView.DataSource = dvjobs
        'set up the currency manager
        cmJobs = CType(BindingContext(dvjobs), CurrencyManager)
 
        'customise the grids - with a strongly typed dataset ...
        '... this could be done in the designer
        ApplicantsDataGridView.ReadOnly = False
        ApplicantsDataGridView.AllowUserToAddRows = False   'Was True.  I don't know why.
        'hide the applicant ID
        'ApplicantsDataGridView.Columns(0).Visible = True    'This is what whas keeping the columns from being hidden
        'hide the job ID ...
        'ApplicantsDataGridView.Columns(1).Visible = True    'This is what whas keeping the columns from being hidden
        'hide the ProgramID column in Applicants DGV
        'ApplicantsDataGridView.Columns(3).Visible = True    'This is what whas keeping the columns from being hidden
        '... but add an unbound column to show ...
        '... the job title matching that ID
        Dim TitleCol As New DataGridViewTextBoxColumn
        'TitleCol.HeaderText = "Job Title"
 
        'ApplicantsDataGridView.Columns(0).Width = 50  'AppID
        'ApplicantsDataGridView.Columns(1).Width = 50  'JobTitleID
        'ApplicantsDataGridView.Columns(2).Width = 100  'LastName
        'ApplicantsDataGridView.Columns(3).Width = 100  'FirstName
        'ApplicantsDataGridView.Columns(4).Width = 150  'Home City
        'ApplicantsDataGridView.Columns(5).Width = 60  'Zip
        'ApplicantsDataGridView.Columns(6).Width = 150  'City Preference
        'ApplicantsDataGridView.Columns(7).Width = 60  'Hours
        'ApplicantsDataGridView.Columns(8).Width = 50  'M-F
        ApplicantsDataGridView.Columns.Add("TitleCol", "Job Title Assigned")
        ApplicantsDataGridView.Columns("TitleCol").DisplayIndex = 7             'This places the JobTitle column on the GridView. It needs to do it this way to update
        'TitleCol.SortMode = DataGridViewColumnSortMode.Automatic        ' <-- This did not make the column sortable.  graye on EE said that it should work, though
        'ApplicantsDataGridView.Sort(ApplicantsDataGridView.Columns("TitleCol"), System.ComponentModel.ListSortDirection.Ascending) ' <---- Got an error with this
 
        '        For example:  <-- An example from graye on Experts Exchange of how he created a ComboBoxcolumn and made it sortable
        '            ' replace the Priority column with a combobox
        '            Dim Priority As New DataGridViewComboBoxColumn()
        '            Priority.DataSource = taPriority.GetActive
        '            Priority.DataPropertyName = "Priority"
        '            Priority.DisplayMember = "PriorityCode"
        '            Priority.Name = "Priority"
        '            Priority.HeaderText = "Pri"
        '            Priority.SortMode = DataGridViewColumnSortMode.Automatic
        '            dgvAssign.Columns.RemoveAt(13)
        '            dgvAssign.Columns.Insert(13, Priority)
        'This works for me....
 
        'ApplicantsDataGridView.Columns("TitleCol").Width = 250  'Job Title
        'ApplicantsDataGridView.Columns(10).Width = 200  'Work Preference
        'ApplicantsDataGridView.Columns(11).Width = 95  'Referred by
        'ApplicantsDataGridView.Columns(12).Width = 50  'Offender
 
        'Dim NumberofAdults As New DataGridViewTextBoxColumn  'Adding column this way did not show any data
        'NumberofAdults.HeaderText = "Adults"                 'Adding it in the designer shows the data
        'ApplicantsDataGridView.Columns.Add(NumberofAdults)   'The above Titlecol column goes on the end
 
        JobTitlesDataGridView.ReadOnly = True
        JobTitlesDataGridView.AllowUserToAddRows = False
        'JobTitlesDataGridView.Columns(0).Visible = False  'Hide JobTitleID
 
 
        'run the sub to fill the jobs numbers displays  ' ------------------Check to see if this needs to e here or just in the Update button-----
        updateTotals()
 
        'get the job titles for the applicants
        For Each dgvr As DataGridViewRow In ApplicantsDataGridView.Rows
            fillInTitle(dgvr)
            'cmApplicants.EndCurrentEdit() '<<< NEW LINE HERE 'This had no apparent affect.  It didn't cause the Job Title column to fill in on form load
            'ApplicantsDataGridView.EndEdit()  'This didn't do it either.
        Next
 
        dvjobs.RowFilter = "txtWorksiteJobTitlePositionsNumber > 0"   '<<<<<Moved to end of YouthJob_Load from above.
 
        'update TextBoxes for count of SYEP, STEPS and Fort Lauderdale Kids - IN Form_Load, UpdateTotals and btnRefresh_Click
        txtSYEP.Text = Me.ApplicantsTableAdapter.CountSYEPActivity().ToString  'The TableAdapter did have: "WHERE (ddlActivityType like '%SYEP%') AND (keyApplicantID > 200900000)" now it's: Status = '1'
        txtSTEPS.Text = Me.ApplicantsTableAdapter.CountWIAActivity().ToString 'No STEPS program for SYEP 2008
        txtFTLauderdale.Text = Me.ApplicantsTableAdapter.CountFtLauderdaleActivity().ToString
        txtConsideredCount.Text = Me.ApplicantsTableAdapter.CountConsidered().ToString
 
        'This just pops the current deployment version number into that label in the top right corner e.g. v1.0.0.51
        If System.Deployment.Application _
        .ApplicationDeployment.IsNetworkDeployed Then
            lblVersion.Text = "v" & System.Deployment.Application _
            .ApplicationDeployment.CurrentDeployment.CurrentVersion.ToString
        Else
            lblVersion.Text = "v" & My.Application.Info.Version.ToString
        End If
 
    End Sub
    Private Sub YouthJob_Closing(ByVal sender As Object, ByVal e As System.ComponentModel.CancelEventArgs) Handles MyBase.Closing
        'make sure any outstanding edits are committed to the datatables
        cmApplicants.EndCurrentEdit()
        cmJobs.EndCurrentEdit()
        'then save datatable changes to database        
        Me.ApplicantsTableAdapter.Update(Me.SYEP2007DataSet.Applicants)
        Me.JobTitlesTableAdapter.Update(Me.SYEP2007DataSet.JobTitles)
 
    End Sub
 
    ''This function is to get the currently selected row of JobTitlesDataGridView in order to return to the selected row after an assignment update.
    'Public Function getDGindex(ByVal ValueToLook As Integer) As Integer
    '    Dim dr As DataGridViewRow
    '    For Each dr In JobTitlesDataGridView.Rows 'DataGridView1.Rows
    '        If dr.Cells("JobTitleID").Value = ValueToLook Then
    '            Return dr.Index
    '        End If
    '    Next
    'End Function
 
    Function getJobTitleIndex(ByVal ID As Integer) As Integer
        For Each row As DataGridViewRow In Me.JobTitlesDataGridView.Rows
            If row.Cells(19).Value = ID Then
                Return row.Index
            End If
        Next
    End Function
    Function getApplicantIndex(ByVal ID As Integer) As Integer
        For Each row As DataGridViewRow In Me.ApplicantsDataGridView.Rows
            If row.Cells(5).Value = ID Then
                Return row.Index
            End If
        Next
    End Function
 
    Private Sub btnUpdatePosition_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnUpdatePosition.Click
        ' ' -=== Assign Worksite to Youth Button ===-
        ' 'Call the function to get the currently selected row of JobTitlesDataGridView
        'Dim myPreviousValue As Long = Me.JobTitlesDataGridView.SelectedRows.Item(0).Cells(19).Value
        ' Stores the current row number
        ' Check if there's any selected row
        'If Not Me.JobTitlesDataGridView.SelectedRows Is Nothing Then 'CurrentRow Is Nothing Then
        If Me.JobTitlesDataGridView.SelectedRows.Count > 0 Then
            'If Not Me.ApplicantsDataGridView.SelectedRows Is Nothing Then 'CurrentRow Is Nothing Then
            If Me.ApplicantsDataGridView.SelectedRows.Count > 0 Then
 
                Dim SelectedID As Integer = Me.JobTitlesDataGridView.CurrentRow.Cells(19).Value
                Dim SelectedID2 As Integer = Me.ApplicantsDataGridView.CurrentRow.Cells(5).Value
 
                Me.Cursor = Cursors.WaitCursor
                Call UpdateAll()
                Call RefreshAll()
                Me.Cursor = Cursors.Default
 
                ' Set the old position
                Dim DGVindex As Integer = getJobTitleIndex(SelectedID)
                Me.JobTitlesDataGridView.ClearSelection()
                Me.JobTitlesDataGridView.Rows(DGVindex).Selected = True
                Me.JobTitlesDataGridView.FirstDisplayedScrollingRowIndex = DGVindex
 
                Dim DGVindex2 As Integer = getApplicantIndex(SelectedID2)
                Me.ApplicantsDataGridView.ClearSelection()
                Me.ApplicantsDataGridView.Rows(DGVindex2).Selected = True
                Me.ApplicantsDataGridView.FirstDisplayedScrollingRowIndex = DGVindex2
 
                Me.JobTitlesDataGridView.ClearSelection()
                Me.ApplicantsDataGridView.ClearSelection()
 
            Else
                Exit Sub
            End If
        End If
        ''Restore the previously selected row after an update.
        'Dim myRowIndex As Integer = getDGindex(myPreviousValue)
        'Me.JobTitlesDataGridView.Rows(myRowIndex).Selected = True
        'Me.JobTitlesDataGridView.FirstDisplayedScrollingRowIndex = myRowIndex
 
        ''Maybe put here UpdateTotals() then RefreshAll()  'Note for 20090312
        ''UpdateTotals() is already called in UpdateAll()
 
 
    End Sub
    Private Sub UpdateAll()
        Dim jobRow As DataRow()
        'use the currency manager to get the currently ...
        '... selected job in the jobs grid
        Dim jobsRow As DataRowView = CType(cmJobs.Current, DataRowView)
        'and save the job number
        Dim newJobNumber As Integer = CInt(jobsRow("keyJobTitleID"))
        'similar for the applicants
        Dim applicantsRow As DataRowView = CType(cmApplicants.Current, DataRowView)
        'check if this applicant already has a job
        If Not TypeOf (applicantsRow.Item("keyJobTitleID")) Is DBNull Then
            'if so, seek the relevant row from the datatable
            jobRow = dtJobs.Select("keyJobTitleID = " & Convert.ToString(applicantsRow.Item("keyJobTitleID")))
            'if there is one
            If jobRow.Length > 0 Then
                'it will be the first in the row array: update it
                Dim myVal As Integer = CInt(jobRow(0).Item("txtWorksiteJobTitlePositionsNumber"))
                myVal += 1 'or myVal = myVal + 1
                jobRow(0).Item("txtWorksiteJobTitlePositionsNumber") = myVal
            Else
                'if there isn't one ...
                MsgBox("Something wrong")
            End If
        End If
        'put the new job number in the applicant's record
        applicantsRow.Item("keyJobTitleID") = newJobNumber
        'decrement the number of jobs available
        'seek the relevant row from the datatable
        jobRow = dtJobs.Select("keyJobTitleID = " & newJobNumber)
        'if there is one
        If jobRow.Length > 0 Then
            'it will be the first in the row array: update it
            Dim myVal As Integer = CInt(jobRow(0).Item("txtWorksiteJobTitlePositionsNumber"))
            myVal -= 1 'or myVal = myVal - 1
            jobRow(0).Item("txtWorksiteJobTitlePositionsNumber") = myVal
        Else
            'if there isn't one ...
            MsgBox("Something wrong")
        End If
 
        ''commit the edits - this is necessary where ...
        ''... they have been done by via the currency ...
        ''... manager's Current record, rather than ...
        ''... (as above) in the datatable itself
        cmApplicants.EndCurrentEdit()
        cmJobs.EndCurrentEdit()
 
        'run the sub to update the jobs numbers displays
        Call updateTotals()
 
        'get the job title for this applicant
        Dim dgvr As DataGridViewRow = ApplicantsDataGridView.CurrentRow
        fillInTitle(dgvr)
 
        'make sure any outstanding edits are committed to the datatables
        cmApplicants.EndCurrentEdit()
        cmJobs.EndCurrentEdit()
        'then save datatable changes to database        
        Me.ApplicantsTableAdapter.Update(Me.SYEP2007DataSet.Applicants)
        Me.JobTitlesTableAdapter.Update(Me.SYEP2007DataSet.JobTitles)
 
    End Sub
 
    Private Sub btnCancelPosition_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnCancelPosition.Click
        Me.Close()
    End Sub
 
    Private Sub cmJobs_PositionChanged(ByVal sender As Object, ByVal e As System.EventArgs) Handles cmJobs.PositionChanged
        'the jobs currency manager was declared WithEvents ...
        '... to make it easy to update the jobs numbers ...
        '... displays when a different job was selected ...
        '... in the grid
        If cmJobs.Count > 0 Then
            updateTotals()
        End If
    End Sub
 
    Private Sub updateTotals()
        If cmJobs.Count = 0 Then
            txtAvailable.Text = ""
            txtTaken.Text = ""
            txtTotal.Text = ""
            MsgBox("No more jobs")
            Exit Sub
        End If
        'use the currency manager to get the currently ...
        '... selected job in the jobs grid
        Dim jobsRow As DataRowView = CType(cmJobs.Current, DataRowView)
        'that says how many of that job are available
        Dim available As Integer = CInt(jobsRow.Item("txtWorksiteJobTitlePositionsNumber"))
        'get the job ID from that row
        Dim thisJob As Integer = CInt(jobsRow.Item("keyJobTitleID"))
        'use the job ID to find how many applicants ...
        '... already have that job
        Dim taken As Integer = CInt(dtApplicants.Compute("Count(keyJobTitleID)", "keyJobTitleID = " & thisJob))
        'the total is the sum of those two
        Dim total As Integer = available + taken
        'display the results
        txtAvailable.Text = available.ToString
        txtTaken.Text = taken.ToString
        txtTotal.Text = total.ToString
 
        ''update TextBoxes with Available, Taken and Total Job Positions
        ''ERROR:  There is already an open DataReader associated with this Command which must be closed first.
        txtPAvailable.Text = Me.JobTitlesTableAdapter.spSUM_JobTitles_PositionsAvailable().ToString
        txtPTaken.Text = Me.JobTitlesTableAdapter.spSUM_JobTitles_PositionsTaken().ToString
        txtPTotal.Text = Me.JobTitlesTableAdapter.spSUM_JobTitles_PositionsTotal().ToString
 
        'update TextBoxes for count of SYEP, STEPS and Fort Lauderdale Kids - IN Form_Load, UpdateTotals and btnRefresh_Click
        txtSYEP.Text = Me.ApplicantsTableAdapter.CountSYEPActivity().ToString
        txtSTEPS.Text = Me.ApplicantsTableAdapter.CountWIAActivity().ToString   ' No STEPS Program for SYEP 2008
        txtFTLauderdale.Text = Me.ApplicantsTableAdapter.CountFtLauderdaleActivity().ToString
        txtConsideredCount.Text = Me.ApplicantsTableAdapter.CountConsidered().ToString
 
        'make sure any outstanding edits are committed to the datatables
        cmApplicants.EndCurrentEdit()
        cmJobs.EndCurrentEdit()
        'then save datatable changes to database        
        Me.ApplicantsTableAdapter.Update(Me.SYEP2007DataSet.Applicants)
        Me.JobTitlesTableAdapter.Update(Me.SYEP2007DataSet.JobTitles)
    End Sub
 
    Private Function getTitleFromID(ByVal ID As Integer) As String
        'Temporary line for debugging purposes
        'If that is reporting 0, then we know the problem is with the datatable.  
        'If it is reporting more than that, then the problem is with either the value 
        'that is being passed to the function, 
        'or with the syntax or references in the select statement.
        'Debug.WriteLine(dtJobs.Rows.Count)
 
        'use datatable filter to return only rows with this ID
        Dim dr As DataRow() = dtJobs.Select("keyJobTitleID = " & ID)
        'check if there are any such rowsI
        If dr.Length > 0 Then
            'if yes, there should only be one - in position 0
            'return the value in the JobName field from that
            '          Return CStr(dr(0)("txtWorksiteJobTitle"))
            Dim s As String = CStr(dr(0)("txtWorksiteJobTitle"))
            ' MsgBox("| s = " & s & "|")  'Here for troubleshooting
            Return s
        Else
            'otherwise, return empty string
            Return ""
        End If
    End Function
 
    Private Sub fillInTitle(ByVal dgvr As DataGridViewRow)
        'check if there is a value in the third cell ...
        '... (index 2, which is the "Job" field ...
        '... in this row from the datagridview
        If TypeOf dgvr.Cells("KeyJobTitleIDDataGridViewTextBoxColumn").Value Is DBNull Then
            'if not, then there is no Job Title
            dgvr.Cells("TitleCol").Value = ""
        Else
            'if there is, use it to get the Job Title
            'Debug.WriteLine("Cell 2 = " & CInt(dgvr.Cells(2).Value))  'I didn't see anything unusual in the debug window when this ran.
            'MsgBox("Cell 2 = " & CInt(dgvr.Cells(2).Value))  '  Here for troubleshooting.
            dgvr.Cells("TitleCol").Value = getTitleFromID(CInt(dgvr.Cells("KeyJobTitleIDDataGridViewTextBoxColumn").Value))
            'Debug.WriteLine("Cell 4 = '" & CInt(dgvr.Cells(4).Value) & "'")
            'MsgBox("Cell 4 = '" & CStr(dgvr.Cells(4).Value) & "'")   'Here for troubleshooting.
            'MsgBox("Cell 4 = '" & CStr(dgvr.Cells("TitleCol").Value) & "'")
        End If
 
 
    End Sub
 
    Private Sub ApplicantsDataGridView_DataError(ByVal sender As Object, ByVal e As System.Windows.Forms.DataGridViewDataErrorEventArgs) Handles ApplicantsDataGridView.DataError
        Debug.WriteLine(e.ColumnIndex)
        Debug.WriteLine(e.RowIndex)
        Debug.WriteLine(ApplicantsDataGridView.Rows(e.RowIndex).Cells(e.ColumnIndex).Value)
        Debug.WriteLine(ApplicantsDataGridView.Rows(e.RowIndex).Cells(e.ColumnIndex).EditedFormattedValue)
        e.ThrowException = True
    End Sub
 
    Private Sub btnRefresh_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnRefresh.Click
        RefreshAll()
    End Sub
    Private Sub RefreshAll()
        ''get the job titles for the applicants
        ''I copied this from the bottom of YouthJob_Load in an attempt to make the Applicants DGV update the Job Titles after a column sort.
        For Each dgvr As DataGridViewRow In ApplicantsDataGridView.Rows
            fillInTitle(dgvr)
            'cmApplicants.EndCurrentEdit() '<<< NEW LINE HERE 'This had no apparent affect.  It didn't cause the Job Title column to fill in on form load
            'ApplicantsDataGridView.EndEdit()  'This didn't do it either.
        Next
 
        'update TextBoxes for count of SYEP, STEPS and Fort Lauderdale Kids - IN Form_Load, UpdateTotals and btnRefresh_Click
        txtSYEP.Text = Me.ApplicantsTableAdapter.CountSYEPActivity().ToString
        txtSTEPS.Text = Me.ApplicantsTableAdapter.CountWIAActivity().ToString   'No STEPS Program for SYEP 2008
        txtFTLauderdale.Text = Me.ApplicantsTableAdapter.CountFtLauderdaleActivity().ToString
        txtConsideredCount.Text = Me.ApplicantsTableAdapter.CountConsidered().ToString
 
        'make sure any outstanding edits are committed to the datatables
        cmApplicants.EndCurrentEdit()
        cmJobs.EndCurrentEdit()
        'then save datatable changes to database        
        Me.ApplicantsTableAdapter.Update(Me.SYEP2007DataSet.Applicants)
        Me.JobTitlesTableAdapter.Update(Me.SYEP2007DataSet.JobTitles)
 
        'Update Applicants(keyWorksiteID, keyEmployerID, WorksiteName, EmployerName) from JobTitles(keyWorksiteID, keyEmployerID, WorksiteName, EmployerName) in the database tables
        Try
            Me.ApplicantsTableAdapter.spUpdate_Applicants_WorksiteName_From_JobTitles()
            Me.ApplicantsTableAdapter.spUpdate_Applicants_CityName_From_tblCities(Me.SYEP2007DataSet.Applicants)
            Me.ApplicantsTableAdapter.spUpdate_Applicants_ZipCode_From_tblZips(Me.SYEP2007DataSet.Applicants)
            'Me.ApplicantsTableAdapter.spUpdate_Applicants_WorkersCompCode(Me.SYEP2007DataSet.Applicants)  '###### Check on this occasionally - It should be fine.
            Me.ApplicantsTableAdapter.spUpdate_Applicants_WorksiteCityPreference(Me.SYEP2007DataSet.Applicants)
            Me.JobTitlesTableAdapter.FillBy1(Me.SYEP2007DataSet.JobTitles) ' runs spUpdate_JobTitles_WorksiteName Re-loads JobTitles. Need to refresh JobTitles GridView
            Me.JobTitlesTableAdapter.spUpdate_JobTitles_EmployerName(Me.SYEP2007DataSet.JobTitles)  'runs spUpdate_JobTitles_EmployerName to put Employer Names into the GridView
            Me.JobTitlesTableAdapter.spUpdate_JobTitles_WorksiteCity(Me.SYEP2007DataSet.JobTitles) '****** Copy this Try/Catch to the Load Event
            Me.JobTitlesTableAdapter.spUpdate_JobTitles_WorksiteZip(Me.SYEP2007DataSet.JobTitles)
            Me.JobTitlesTableAdapter.spUpdate_JobTitles_PositionsAvailable(Me.SYEP2007DataSet.JobTitles)
            Me.JobTitlesTableAdapter.spUpdate_JobTitles_PositionsTaken(Me.SYEP2007DataSet.JobTitles)
        Catch ex As System.Exception
            System.Windows.Forms.MessageBox.Show(ex.Message)
        End Try
 
        '*****Start  Copied from the Load Event *****  Not sure if all lines are necessary
        Try
            Me.JobTitlesTableAdapter.Fill(Me.SYEP2007DataSet.JobTitles)
        Catch ex As Exception
            MessageBox.Show(ex.StackTrace)
        End Try
        'Try
        '    Me.ApplicantsTableAdapter.Fill(Me.SYEP2007DataSet.Applicants)
        'Catch ex As Exception
        '    MessageBox.Show(ex.StackTrace)
        'End Try
 
        'dtApplicants = Me.SYEP2007DataSet.Applicants
        'dtJobs = Me.SYEP2007DataSet.JobTitles
        '*****End  Copied from the Load Event *****  Not sure if all lines are necessary
 
        ''#####  Start  Update Positions Available, Positions Taken and Total in DataGridView  Note !!!  PositionsAvailable and txtPositions are labeled backwards !!!
        'Try
        'Me.JobTitlesTableAdapter.spUpdate_JobTitles_PositionsAvailable(Me.SYEP2007DataSet.JobTitles)
        'Me.JobTitlesTableAdapter.spUpdate_JobTitles_PositionsTaken(Me.SYEP2007DataSet.JobTitles)
        'Catch ex As Exception
        '    System.Windows.Forms.MessageBox.Show(ex.Message)
        'End Try
        ''#####  End    Update Positions Available, Positions Taken and Total in DataGridView  Note !!!  PositionsAvailable and txtPositions are labeled backwards !!!
        '*****Start  Copied from the btn2008 Event to repopulate the Applicants GridView after a btnRefresh - Must be last *****  
        Try
            Me.ApplicantsTableAdapter.FillBy3(Me.SYEP2007DataSet.Applicants)
        Catch ex As System.Exception
            System.Windows.Forms.MessageBox.Show(ex.Message)
        End Try
        '*****End  Copied from the btn2008 Event to repopulate the Applicants GridView after a btnRefresh *****  
 
        ''get the job titles for the applicants '## Copied from Private Sub ApplicantsDataGridView_ColumnHeaderMouseClick right below so that when the 
        ''Refresh button is clicked it will update the JobTitles column because the Refresh button was clearing the column and I had to then click
        '' the ColumnHeader of the JobTitles column to get the job titles back.  This should do it automatically.
        ''I copied this from the bottom of YouthJob_Load in an attempt to make the Applicants DGV update the Job Titles after a column sort.
        For Each dgvr As DataGridViewRow In ApplicantsDataGridView.Rows
            fillInTitle(dgvr)
            'cmApplicants.EndCurrentEdit() '<<< NEW LINE HERE 'This had no apparent affect.  It didn't cause the Job Title column to fill in on form load
            'ApplicantsDataGridView.EndEdit()  'This didn't do it either.
        Next
 
    End Sub
    Private Sub ApplicantsDataGridView_ColumnHeaderMouseClick(ByVal sender As Object, ByVal e As System.Windows.Forms.DataGridViewCellMouseEventArgs) Handles ApplicantsDataGridView.ColumnHeaderMouseClick
        ''get the job titles for the applicants
        ''I copied this from the bottom of YouthJob_Load in an attempt to make the Applicants DGV update the Job Titles after a column sort.
        For Each dgvr As DataGridViewRow In ApplicantsDataGridView.Rows
            fillInTitle(dgvr)
            'cmApplicants.EndCurrentEdit() '<<< NEW LINE HERE 'This had no apparent affect.  It didn't cause the Job Title column to fill in on form load
            'ApplicantsDataGridView.EndEdit()  'This didn't do it either.
        Next
    End Sub
    Private Sub FillByToolStripButton_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles FillByToolStripButton.Click
        Try
            Me.ApplicantsTableAdapter.FillBy(Me.SYEP2007DataSet.Applicants)
        Catch ex As System.Exception
            System.Windows.Forms.MessageBox.Show(ex.Message)
        End Try
    End Sub
    Private Sub btnConsideredFilter_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnConsideredFilter.Click
        Try
            Me.ApplicantsTableAdapter.FillBy(Me.SYEP2007DataSet.Applicants)
        Catch ex As System.Exception
            System.Windows.Forms.MessageBox.Show(ex.Message)
        End Try
        For Each dgvr As DataGridViewRow In ApplicantsDataGridView.Rows
            fillInTitle(dgvr)
            'cmApplicants.EndCurrentEdit() '<<< NEW LINE HERE 'This had no apparent affect.  It didn't cause the Job Title column to fill in on form load
            'ApplicantsDataGridView.EndEdit()  'This didn't do it either.
        Next
        btnSYEPFilter.BackColor = Color.LightGray
        btnConsideredFilter.BackColor = Color.Violet
        btnFtLauderdaleFilter.BackColor = Color.LightGray
        btn2008.BackColor = Color.LightGray
 
    End Sub
 
    Private Sub FillBy1ToolStripButton_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles FillBy1ToolStripButton.Click
        Try
            Me.ApplicantsTableAdapter.FillBy1(Me.SYEP2007DataSet.Applicants)
        Catch ex As System.Exception
            System.Windows.Forms.MessageBox.Show(ex.Message)
        End Try
    End Sub
 
    Private Sub btnSYEPFilter_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnSYEPFilter.Click
        'For 2009 there are no STEPS so I made this filter on Status = '1' instead.  The button says "Status 1".
        Try
            Me.ApplicantsTableAdapter.FillBy1(Me.SYEP2007DataSet.Applicants)
        Catch ex As System.Exception
            System.Windows.Forms.MessageBox.Show(ex.Message)
        End Try
 
        ''get the job titles for the applicants
        ''I copied this from the bottom of YouthJob_Load in an attempt to make the Applicants DGV update the Job Titles after a column sort.
        For Each dgvr As DataGridViewRow In ApplicantsDataGridView.Rows
            fillInTitle(dgvr)
            'cmApplicants.EndCurrentEdit() '<<< NEW LINE HERE 'This had no apparent affect.  It didn't cause the Job Title column to fill in on form load
            'ApplicantsDataGridView.EndEdit()  'This didn't do it either.
        Next
        btnSYEPFilter.BackColor = Color.Violet
        btnConsideredFilter.BackColor = Color.LightGray
        btnFtLauderdaleFilter.BackColor = Color.LightGray
        btn2008.BackColor = Color.LightGray
 
    End Sub
    Private Sub btnFtLauderdaleFilter_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnFtLauderdaleFilter.Click
        Try
            Me.ApplicantsTableAdapter.spFilter_FtLauderdaleKids(Me.SYEP2007DataSet.Applicants) '.Fill Applicants Table Adapter with Fort Lauderdale Kids only
        Catch ex As System.Exception
            System.Windows.Forms.MessageBox.Show(ex.Message)
        End Try
        btnSYEPFilter.BackColor = Color.LightGray
        btnConsideredFilter.BackColor = Color.LightGray
        btnFtLauderdaleFilter.BackColor = Color.Violet
        btn2008.BackColor = Color.LightGray
 
    End Sub
 
    Private Sub FillBy2ToolStripButton_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles FillBy2ToolStripButton.Click
        Try
            Me.ApplicantsTableAdapter.FillBy2(Me.SYEP2007DataSet.Applicants)
        Catch ex As System.Exception
            System.Windows.Forms.MessageBox.Show(ex.Message)
        End Try
    End Sub
 
    Private Sub txtAllFilter_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles txtAllFilter.Click
        'All 07-09 Button
        Try
            Me.ApplicantsTableAdapter.FillBy2(Me.SYEP2007DataSet.Applicants)
        Catch ex As System.Exception
            System.Windows.Forms.MessageBox.Show(ex.Message)
        End Try
        ' Put Total of all Applicants from all years into Text Box.  Sp counts all applicants.
        Dim count As Integer = CType(Me.ApplicantsTableAdapter.spCount_AllApplicants, Integer)
        txtTotalApplicants.Text = String.Format("{0} Applicants", count)
 
    End Sub
    Private Sub test()
        'Just testing how to convert a string to Proper Case.  Names like McIntire are problematic.
        Dim myTest As String
        myTest = StrConv("test", VbStrConv.ProperCase)
    End Sub
 
    Private Sub btn2008_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btn2008.Click
        '2009 Button
        Try
            Me.ApplicantsTableAdapter.FillBy3(Me.SYEP2007DataSet.Applicants)
        Catch ex As System.Exception
            System.Windows.Forms.MessageBox.Show(ex.Message)
        End Try
 
        ''get the job titles for the applicants '## Copied from Private Sub ApplicantsDataGridView_ColumnHeaderMouseClick right below so that when the 
        ''Refresh button is clicked it will update the JobTitles column because the Refresh button was clearing the column and I had to then click
        '' the ColumnHeader of the JobTitles column to get the job titles back.  This should do it automatically.
        ''I copied this from the bottom of YouthJob_Load in an attempt to make the Applicants DGV update the Job Titles after a column sort.
        For Each dgvr As DataGridViewRow In ApplicantsDataGridView.Rows
            fillInTitle(dgvr)
            'cmApplicants.EndCurrentEdit() '<<< NEW LINE HERE 'This had no apparent affect.  It didn't cause the Job Title column to fill in on form load
            'ApplicantsDataGridView.EndEdit()  'This didn't do it either.
        Next
        ' Put total of 2009 Applicants into the text box. The sp counts 2009 Applicants
        Dim count As Integer = CType(Me.ApplicantsTableAdapter.spCount_Applicants2008Total, Integer)
        txtTotalApplicants.Text = String.Format("{0} Applicants", count)
        btnSYEPFilter.BackColor = Color.LightGray
        btnConsideredFilter.BackColor = Color.LightGray
        btnFtLauderdaleFilter.BackColor = Color.LightGray
        btn2008.BackColor = Color.Violet
 
    End Sub
    Private Sub btnWIA_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnWIA.Click
        'Filter Applicants Grid on WIA in txtActivityType field
        'spFilter_WIA_Applicants
        Try
            Me.ApplicantsTableAdapter.spFilter_WIA_Applicants(Me.SYEP2007DataSet.Applicants) '.Fill Applicants Table Adapter with WIA 19-24 yo Kids only
        Catch ex As System.Exception
            System.Windows.Forms.MessageBox.Show(ex.Message)
        End Try
        btnSYEPFilter.BackColor = Color.LightGray
        btnConsideredFilter.BackColor = Color.LightGray
        btnFtLauderdaleFilter.BackColor = Color.LightGray
        btn2008.BackColor = Color.LightGray
        btnWIA.BackColor = Color.Violet
    End Sub
 
End Class

Open in new window

YouthJob.vb.png
YouthJob.vb.running.png
YouthJob.DataSet.png
StoredProcedures.zip
0
megnin
Asked:
megnin
  • 10
  • 10
2 Solutions
 
Bob LearnedCommented:
OK, so where do we go from here?  That sounds like a very large question, and I can see why it has been sitting without comment.  

Musings:

1) Think about studying the model-view-controller/model-view-presenter design pattern.  It can help you with "business" code separation from "UI" code.

2) Think about single-purpose classes, instead of one monster class.

3) Think about n-tier develop with a data access layer, business layer, and presentation layer.

4) Think about logging exceptions, with something like Enterprise library, or log4net, instead of Debug.WriteLine.

5) Think about keeping code a little tidier.  Commenting code is an exceptable practice, but put a date when you comment, and then remove those commented lines after a certain number of days--a month, 90 days, whatever you feel comfortable with.

6) Think about object-oriented programming, with base classes, interfaces, polymorphism, etc.
0
 
Arthur_WoodCommented:
In addition to TheLearnedOne's excellent comments, the one think that also stands out to me is the excessive use of the construct "Me."- that is completely un-necessary.  You do not need to specify Me.  on almost every line of your code.

AW
0
 
Bob LearnedCommented:
Aside--"Me" can help with Intellisense for a class, but is not a necessary construct for software design.
0
Concerto's Cloud Advisory Services

Want to avoid the missteps to gaining all the benefits of the cloud? Learn more about the different assessment options from our Cloud Advisory team.

 
megninAuthor Commented:
Thank you both very much for taking the time to even respond to my "very large" question.  I realize that it's a bit broad in scope an not really the norm for this forum.

My situation is, my company promoted me from "help desk technician" to "programmer" because I showed an apptitude for it, though I had never been a programmer, just dabbled in VBA in excel, mostly recording macros rather than writing them myself.  The first thing they did was to give me a large (large for me) project and I've been scrambling to keep up ever since. I'm too busy working on and patching and debugging this and other projects to actually learn how to program.  It seems like a catch 22; if I try to take time to read or study I get behind in my work.

Anyway, about your "Musings", LearnedOne...
1)  I'll Google "model-view-controller/model-view-presenter design pattern".  Those terms are new to me.
2) Single-purpose classes?  I think I see what you are saying, but I'm not sure how to go about it.  (Keep in mind we have no other programmers for me to learn from).  I can Google for examples and tutorials.
3) I have heard of N-Tier development. ;-)  With projects here being sort of thrown at me with the "Can you have this application created by this afternoon?  The people we didn't tell you would need it will be here at 2:00 P.M." attitude, I haven't taken the time to learn to do it properly I just been throwing the code together as quickly and simply as possible to get something barely workable in place just as soon as possible.  I mention "Testing" around here and I just get a blank stare.
4) I was wondering what that "Debug.WriteLine" thing was doing.  ;-)  Are Enterprise library or log4net expensive (we're a non-profit) or complicated to implement in a very small development environment.
5) I'll try to keep it tidier.  I still need to learn what tidy code looks like though.  I've been leaving all the comments and even old commented out code to memind me of what is going on in that area of code.  A lot of the code I barely understand how it works and some of it I simply do not know what's going on or how it works at all, so I need the comments to let me know that it's needed for some function or another, or it may be replacing a piece of code that didn't work, but I understood what it was suppose to do, so it helps me understand what the new code is doing.  I know it's sloppy.
6) [blank stare] ;-)  I barely understand those concepts and I really don't know what is meant by "base classes".

I'm sorry; I'm really a novice with no trainging an only experience in creating bad habits.  

Arthur Wood,  I did not know that the "Me." constructs were un-necessary.  I've copied and pasted most of my code from either examples I've found "Googling" or answers to questions I've either found here on EE or asked here on EE, including much assistance from TheLearnedOne over the past year or so.

What I would really like to have is one or all of the below:
A very patient mentor
A good training class
Lots of time to read books

Both of your comments and musings are very helpful in pointing me towards things I need to learn.  I appreciate them very much.  

Any other suggestions, either toward learning resources or directly related to this project are greatly appriciated.  :-)  (I really don't have to use "Me."?)
0
 
Bob LearnedCommented:
Enterprise Library and log4net are free for you to download.

Modular code means that you can separate your code in pieces, and re-use them without having to rip and tear.   Single-purpose classes, and methods move you towards modular code.  MVC (model-view-controller) is another step towards modular, since it separates the UI logic from the "business" logic.

Learning good strategies, good code construction skills, and developing good habits early helps you grow your personal knowledge faster, and gives your code a strength that it wouldn't have otherwise.

What you described, where code grows beyond your capabilities to keep control, sounds like a little like the second-system effect.

Wikipedia -- Second-system effect
http://en.wikipedia.org/wiki/Second-system_effect

"In computing, the second-system effect or sometimes the second-system syndrome refers to the tendency, when following on from a relatively small, elegant, and successful system, to design the successor as an elephantine, feature-laden monstrosity. The term was first used by Fred Brooks in his classic The Mythical Man-Month.[1] It described the jump from a set of simple operating systems on the IBM 700/7000 series to OS/360 on the 360 series."

This effect can be seen if you don't have a complete understanding about the architecture, and adding features without understanding the architectural impact.
0
 
megninAuthor Commented:
Second-system effect... yes, that exactly describes my project, I'm afraid.

I do want to make this thing modular and structured better, but I don't have any framework to base it on or any experience to base a design on.  I kind of just started with a form, threw two DataGridViews on it and then tacked stuff onto it as I went.  There is no structure, form or plan to it.

Your last statement also hits the nail right on the head.
0
 
megninAuthor Commented:
I found this in a VB 2008 Tutorial explaining Object Oriented Programming:

Encapsulation refers to the creation of self-contained modules that bind processing functions to the data. These user-defined data types are called classes. Each class contains data as well as a set of methods which manipulate the data. The data components of a class are called instance variables and one instance of a class is an object. For example, in a library system, a class could be member, and John and Sharon could be two instances (two objects) of the library class.

Inheritance
Classes are created according to  hierarchies, and inheritance allows the structure and methods in one class to be passed down the hierarchy. That means less programming is required when adding functions to complex systems. If a step is added at the bottom of a hierarchy, then only the processing and data associated with that unique step needs to be added. Everything else about that step is inherited. The ability to reuse existing objects is considered a major advantage of object technology.

Polymorphism
Object-oriented programming allows procedures about objects to be created whose exact type is not known until runtime. For example, a screen cursor may change its shape from an arrow to a line depending on the program mode. The routine to move the cursor on screen in response to mouse movement would be written for "cursor," and polymorphism allows that cursor to take on whatever shape is required at runtime. It also allows new shapes to be easily integrated.

This seems to be a helpful explanation.
0
 
Bob LearnedCommented:
There is a point where I can give you too much to process, so let me know when you are full...

Coupling (with Cohesion, Dependency)
http://en.wikipedia.org/wiki/Coupling_(computer_science)

"Coupling is usually contrasted with cohesion. Low coupling often correlates with high cohesion, and vice versa...Low coupling refers to a relationship in which one module interacts with another module through a stable interface and does not need to be concerned with the other module's internal implementation (see Information Hiding). With low coupling, a change in one module will not require a change in the implementation of another module. Low coupling is often a sign of a well-structured computer system, and when combined with high cohesion, supports the general goals of high readability and maintainability."
0
 
Bob LearnedCommented:
Cyclomatic complexity
http://en.wikipedia.org/wiki/Cyclomatic_complexity

"...is used to measure the complexity of a program. It directly measures the number of linearly independent paths through a program's source code."
0
 
megninAuthor Commented:
I'm going through these little lessons I found here: http://www.vbtutor.net/vb2008/vb2008tutor.html
which are very basic, but some of the basics, I still need to get a foundation in.

Yes!!! Your Coupling vs Cohesion instructions (I'm reading the Wikipedia page as well) are exactly the kind of information I have been completely missing.

I basically had a hand full of for/next and if/thens and was told, oh yeah you can drag grids on that form too, but I've gotten almost none of the theory or principals that I need.  Please keep them comming.
0
 
Bob LearnedCommented:
Attached is a loosely coupled Model-View-Controller example (without comments).  I would suggest looking through it, creating the class structure to test it, and add your own comments.  Ask any questions for things that need clarification.

Sample usage:

    Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
        Dim controller As New ModelViewController.ProductController(Me)
    End Sub



Imports System.ComponentModel
Imports System.Configuration
Imports System.Data.SqlClient
 
Public Class ModelViewController
 
    Public Class ProductModel
 
        Public Delegate Sub DataChangedEventHandler(ByVal sender As Object, ByVal e As DataChangedEventArgs)
        Public Event DataChanged As DataChangedEventHandler
 
        Private m_productList As New List(Of Product)
        Public ReadOnly Property ProductList() As List(Of Product)
            Get
                Return m_productList
            End Get
        End Property
 
        Public Sub New(ByVal table As DataTable)
            For Each dr As DataRow In table.Rows
                Dim product As New Product(dr)
                AddHandler product.PropertyChanged, AddressOf OnPropertyChanged
                m_productList.Add(Product)
            Next
        End Sub
 
        Private Sub OnPropertyChanged(ByVal sender As Object, ByVal e As PropertyChangedEventArgs)
            RaiseEvent DataChanged(Me, New DataChangedEventArgs(0, e.PropertyName))
        End Sub
 
        Public Class Product
 
            Public Event PropertyChanged As PropertyChangedEventHandler
 
            Public Sub New(ByVal row As DataRow)
                m_productID = row("ProductID")
                m_productName = row("Name")
                m_listPrice = row("ListPrice")
            End Sub
 
            Private m_productID As Integer = 0
            Public Property ProductID() As Integer
                Get
                    Return m_productID
                End Get
                Set(ByVal value As Integer)
                    m_productID = value
                    RaiseEvent PropertyChanged(Me, New PropertyChangedEventArgs("ProductID"))
                End Set
            End Property
 
            Private m_productName As String = ""
            Public Property ProductName() As String
                Get
                    Return m_productName
                End Get
                Set(ByVal value As String)
                    m_productName = value
                    RaiseEvent PropertyChanged(Me, New PropertyChangedEventArgs("ProductName"))
                End Set
            End Property
 
            Private m_quantity As Integer
            Public Property Quantity() As Integer
                Get
                    Return m_quantity
                End Get
                Set(ByVal value As Integer)
                    m_quantity = value
                    RaiseEvent PropertyChanged(Me, New PropertyChangedEventArgs("Quantity"))
                End Set
            End Property
 
            Private m_listPrice As Decimal
            Public Property ListPrice() As Decimal
                Get
                    Return m_listPrice
                End Get
                Set(ByVal value As Decimal)
                    m_listPrice = value
                    RaiseEvent PropertyChanged(Me, New PropertyChangedEventArgs("ListPrice"))
                End Set
            End Property
 
            Public ReadOnly Property Price() As Decimal
                Get
                    Return Me.ListPrice * Me.Quantity
                End Get
            End Property
 
        End Class
 
    End Class
 
    Public Class ProductView
        Inherits DataGridView
 
        Public Sub New()
            Me.Dock = DockStyle.Fill
        End Sub
 
    End Class
 
    Public Class ProductController
 
        Private m_productModel As ProductModel = Nothing
        Private m_productView As ProductView = Nothing
 
        Public Sub New(ByVal parentForm As Form)
            m_productModel = New ProductModel(ProductDataLayer.GetProductList())
            m_productView = New ProductView()
 
            AddHandler m_productView.CellEndEdit, AddressOf OnCellEndEdit
            AddHandler m_productModel.DataChanged, AddressOf OnDataChanged
 
            m_productView.DataSource = m_productModel.ProductList
 
            parentForm.Controls.Add(m_productView)
        End Sub
 
        Private Sub OnCellEndEdit(ByVal sender As Object, ByVal e As DataGridViewCellEventArgs)
            m_productModel.ProductList(e.RowIndex).Quantity = m_productView.Rows(e.RowIndex).Cells(2).Value
        End Sub
 
        Private Sub OnDataChanged(ByVal sender As Object, ByVal e As DataChangedEventArgs)
 
        End Sub
 
    End Class
 
    Public Class ProductDataLayer
 
        Public Shared Function GetProductList() As DataTable
            Dim commandText As String = "SELECT ProductID, Name, ListPrice FROM Production.Product ORDER BY Name"
            Dim connectionString As String = ConfigurationManager.ConnectionStrings("AdventureWorks").ConnectionString
            Using adapter As New SqlDataAdapter(commandText, connectionString)
                Dim data As New DataTable("Product")
                adapter.Fill(data)
                Return data
            End Using
        End Function
 
    End Class
 
    Public Class DataChangedEventArgs
        Inherits EventArgs
 
        Public Sub New(ByVal row As Integer, ByVal propertyName As String)
 
        End Sub
 
        Private m_row As Integer
        Public ReadOnly Property Row() As Integer
            Get
                Return m_row
            End Get
        End Property
 
    End Class
 
End Class

Open in new window

0
 
Bob LearnedCommented:
That code is a work-in-progress, and isn't fully complete, but should get you closer to understanding the MVC pattern.
0
 
megninAuthor Commented:
Thank you!  I'm going to work on that this weekend.  I think that if I can master some of the techniques in that example, my basic understanding will take a leap forward and my programs will benifit that much more.
I see how the classes are each single function modules instead of the haveing a "monster class" with everything piled in.
Thanks again.
0
 
Bob LearnedCommented:
You should also see that the is a separation between data (model), business (controller), and UI (view).  Loose coupling between classes means that you can reuse code without having to rip, shred, and risk breaking existing code.  .NET events use the Observer pattern (aka Publish/Subscribe).  It is like a radio station, that broadcasts music, but the listener chooses whether to listen or not.  Events are raised even if there aren't any listeners.
0
 
megninAuthor Commented:
Okay, I've been able to read the code over and over, but when I tried to put it into Visual Studio to try to figure out what I'm looking at, the error below shows up in Design View.  In installed the Adventure Works DB.  Maybe I'm missing your point, I don't know what the hell I'm doing right now.  It looks very exciting, but I still have trouble making a "Select/Case" work.  ;-)  I don't even know how to load your example to try and look at it.  I'm not frustrated with you. I really appreciate your help and the vast patience you've shown me in the past.  I'm frustrated with my ignorance.  I've been a "programmer" for almost two years and I can't write a "Hello World" program in any language without looking in the book.  I'm very sorry.  I feel like I'm wasting your time.

To prevent possible data loss before loading the designer, the following errors must be resolved:  
 
    1 Error  
 
   The class Form1 can be designed, but is not the first class in the file. Visual Studio requires that designers use the first class in the file. Move the class code so that it is the first class in the file and try loading the designer again.    
     
Instances of this error (1)  
 
1.   Show Call Stack  
 
at System.ComponentModel.Design.Serialization.CodeDomDesignerLoader.EnsureDocument(IDesignerSerializationManager manager)
at System.ComponentModel.Design.Serialization.CodeDomDesignerLoader.PerformLoad(IDesignerSerializationManager manager)
at Microsoft.VisualStudio.Design.Serialization.CodeDom.VSCodeDomDesignerLoader.PerformLoad(IDesignerSerializationManager serializationManager)
at System.ComponentModel.Design.Serialization.BasicDesignerLoader.BeginLoad(IDesignerLoaderHost host)  
   
 
 
0
 
Bob LearnedCommented:
Here are some suggestions:

1) Break that code up into small class modules, so that you can see the forest for the trees.

2) Add a class module for each class (Product, ProductModel, ProductDataLayer, DataChangedEventArgs, ProductView, ProductController).

    Copy and paste the code into each class module.  Make sure that each class module has the right Imports statements.

3) You need to add a .NET reference to System.Configuration.dll, in order to use System.Configuration.ConfigurationManager.

4) That code cannot go into a form's code module--it was meant to go into separate class modules.  That is why you got that designer error, since the Form class needs to be the first class defined.

5) With an existing Form in the project, you can use the sample code shown:

    Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
        Dim controller As New ModelViewController.ProductController(Me)
    End Sub

6) You need to add an app.config file, and a connection string with 'AdventureWorks' as the key.
   
    Storing and Retrieving Connection Strings  
    http://msdn.microsoft.com/en-us/library/ms254494(VS.80).aspx

Realize that I was where you are about 15 years ago, so don't stress about learning everything today (or even tomorrow).  It takes time to learn new concepts, design techniques.  I am still learning, after all these years.
0
 
megninAuthor Commented:
Oh, thank you very much.  Is this maybe a chapter or two beyond where I need to start?  I obviously need to do some reading and studying.  I don't want this to turn into you teaching me how to program; I realize that's not the scope of this forum, but I do very much appreciate all of your suggestions and pointers.  I'm at a point where I don't really know what I should be studying.  I've got the videos on "Beginning Object Oriented Programming" from "LearnVisualStudio.com" (I've a subscription).  

I'm swamped with work today, so I won't get a chance to do the steps above until this evening or later.  I didn't know about needing the reference to the Syetem.Configuration.dll.  That makes sense and I'm glad that's what the problem was.

Yesterday I was trying to drag a table from the AdventurWorks database onto the form, hoping it would create a DataGrid for me and add the connection string like an ASP.Net page will do and put the connection string into the web.config file.  I've done more ASP.Net work than VB.  I'll have to read the reference in step 6) to learn about the app.config file and connection strings in it.

Thanks again.  
0
 
Bob LearnedCommented:
This is approach is beyond what I understand your capabilities are.  Sometimes I feel that it is good to set the bar high so that you can know what the realm of possibilities are, and to set a goal to learn good techniques early, that will give you a clearer path to follow during your learning process.

It is a good practice to not store connection strings in code, since .NET code is easily decompiled.  Storing the connection string in the app.config (or web.config) is one choice that stands above the rest (in my opinion).  The System.Configuration.dll namespace and the ConfigurationManager class make it easy to access application settings and connection strings.
0
 
megninAuthor Commented:
Ah, thank you for telling me exactly what the System.Configuration.dll is for.  There are so many namespaces and it's not always clear exactly what they are for.  It helps to understand what the components in the code are for.

Yes, I agree.  Storing the connection string in the web.config also makes it easier to move the project from one server to another, i.e. I zip up my web form project and take it home to work on it; in the code behind I refer to the connection string like this:
Dim DBConn As New SqlConnection(ConfigurationManager.ConnectionStrings("SYEP2007ConnectionString1").ConnectionString)
I have the connection string in the web.config files both at work and at home with the same name so I don't have to adjust it in the code.

It's a relief to know that you understand that the example is a bit beyond my current capabilities.  I agree that one's reach should exceed their grasp.  

Thank you!
0
 
megninAuthor Commented:
Sorry, TLO, I've been working seven days and haven't had time to devote the attention to this I'd like.  I'd like to keep this thread open until I can digest some of it.  And, maybe in the mean time someone can poke at my code and point out some of the (many) mistakes.
0
 
megninAuthor Commented:
Thank you very much.  I truely value your suggestions and help.  I wish I had a "mentor" with your experience.
0

Featured Post

Free Tool: IP Lookup

Get more info about an IP address or domain name, such as organization, abuse contacts and geolocation.

One of a set of tools we are providing to everyone as a way of saying thank you for being a part of the community.

  • 10
  • 10
Tackle projects and never again get stuck behind a technical roadblock.
Join Now