Why is ListView not refreshing? - vb.net

Hi I am inserting into a table then reading everything back into a ListView When I re-open the program I see the data I just saved in my ListView, but this record is not showing in my ListView at the time of saving (although it is saved in the table).
I am using
listView.Update()
as well as
listView.Refresh()
but it does not seem to work. I am just using a SELECT query to read data off the datareader and store it in my listView as follows (which is working properly)
The only problem is that the listView is not refreshing immediately, but it works when I close/open the program
here's the code I am using at the end of my Save method. basically these two methods get called
Private Sub SetColumns()
Dim lstpenalty As New ListView()
lstpenalty.Items.Clear()
lstpenalty.Visible = True
lstpenalty.Bounds = New Rectangle(New Point(390, 55), New Size(560, 379))
lstpenalty.Name = "lstpenalty"
lstpenalty.FullRowSelect = True
lstpenalty.View = View.Details
lstpenalty.GridLines = True
lstpenalty.Items.Clear()
lstpenalty.Columns.Add("a", 75)
lstpenalty.Columns.Add("b", 70)
lstpenalty.Columns.Add("c", 105)
lstpenalty.Columns.Add("d", 98)
lstpenalty.Columns.Add("e", 90)
lstpenalty.Columns.Add("f", 105)
Me.Controls.Add(lstpenalty)
LoadPenaltyList(lstpenalty)
End Sub
Private Sub LoadPenaltyList(ByRef listView As ListView)
Dim gDR As OracleDataReader
Dim cmd As New OracleCommand
Dim lstpenaltyview As New ListViewItem
Try
cnn.Connect_to_Oper_Agent()
cmd.Connection = cnn.cnn
listView.Items.Clear()
cmd.CommandText = " select a," & _
"b, " & _
"c, " & _
"d," & _
"e," & _
"f" & _
" FROM myTable" & _
" commit"
gDR = cmd.ExecuteReader()
While gDR.Read
lstpenaltyview = listView.Items.Add(Null_To_String(gDR("a")))
lstpenaltyview.SubItems.Add(gDR("b"))
lstpenaltyview.SubItems.Add(gDR("c"))
lstpenaltyview.SubItems.Add(gDR("d"))
lstpenaltyview.SubItems.Add(gDR("e"))
lstpenaltyview.SubItems.Add(gDR("f"))
End While
listView.Update()
Catch ex As Exception
MsgBox("There was an error... -> " & ex.ToString)
Finally
cmd.Dispose()
cnn.Close_Conn()
End Try
End Sub
Thanks for your help

It is worth looking at what methods do.
http://msdn.microsoft.com/en-us/library/system.windows.forms.listview_methods%28v=vs.71%29.aspx
Update : Causes the control to redraw the invalidated regions within its client area.
Refresh: Forces the control to invalidate its client area and immediately redraw itself and any child controls.
To update it using table info, first Clear the listview, then redo the process you used to initially populate it.

So I was creating the ListView dynamically. The issue was that it kept creating ListViews over each other (memory leak), and it always showed the previous one. I created a static viewList versus a dynamic one and the issue is resolved:D

Use
For Each i As Windows.Forms.ListViewItem In ListView1.Items
i.Remove()
Next
Instead of Clear

Related

error occured when clicking a programatically added button [duplicate]

This question already has answers here:
What is a NullReferenceException, and how do I fix it?
(27 answers)
Closed 5 years ago.
I am trying to programatically generate buttons and add event handlers to them and i've succeeded in creating the buttons but when I click on one of the I get the following message object reference not set to an instance of an object .
Here is the code that creates the buttons:
Dim i As Integer = 1
For Each dtab As DataTable In ds.Tables
For Each drow As DataRow In dtab.Rows
If (CInt(drow(3)) < CInt(drow(4))) Then
Dim l As New Label()
With l
.Location = New System.Drawing.Point(30, 40 * i)
.Text = "product number " & drow(0) & " has reached the minimal quantity"
.Width = 300
Panel3.Controls.Add(l)
End With
Dim b As New Button()
With b
.Location = New System.Drawing.Point(350, 40 * i)
.Enabled = True
.Width = 100
.Text = "fill stock"
Panel3.Controls.Add(b)
AddHandler b.Click, AddressOf Me.Button_Click
End With
i = i + 1
End If
Next
Next
the code that handels the button click is the following:
Private Sub Button_Click(ByVal sender As System.Object, ByVal e As System.EventArgs)
Dim co As New SqlConnection("server=JAMMINGJACK-PC\SQLEXPRESS ;initial catalog=td3;integrated security=true;")
Try
Dim cmd As New SqlCommand
co.Open()
cmd.Connection = co
cmd.CommandText = "Update article set qteStck=(qteStck+(seuilmin*3)) where numart=" & drow(0) '
cmd.CommandType = CommandType.Text
cmd.ExecuteNonQuery()
co.Close()
Catch ex As Exception
MsgBox(ex.Message, MsgBoxStyle.Critical, Me.Text)
End Try
End Sub
There are two big problems on this line in your event handler:
cmd.CommandText = "Update article set qteStck=(qteStck+(seuilmin*3)) where numart=" & drow(0) '
The first problem is the code is crazy vulnerable to sql injection attacks. It's a side-issue to the question, but this is IMPORTANT, and you should take a few minutes to Google parameterized queries and how to use them.
The second problem is with the drow(0) expression. That variable has no meaning in this method. It was scoped to the For Each loop in the code that created your buttons, but it has no meaning at all here. That this compiles at all means you either tried to re-declare it at the class level (which won't help; that will be a different drow variable) or turned Option Strict off, which is very poor practice.
There are several ways you can address this, such as encoding the drow(0) value in theTag property or inferring it from the Name. My preferred approach here would be to create a custom control that groups your label and button together.

DataGridView - Concurrency Issue When Updating or Deleting New Records

I have a problem with a DataGridView based application. After adding records to the grid, if I subsequently attempt to update or delete the new records I get the following respective errors.
Concurrency violation: the UpdateCommand affected 0 of the expected 1 records.
Concurrency violation: the DeleteCommand affected 0 of the expected 1 records.
A save of the dataset is enforced in the RowValidated event.
Private Sub uxGrid_RowValidated(sender As Object, e As DataGridViewCellEventArgs) Handles uxGrid.RowValidated
If IsDGVRowDirty(sender, e.RowIndex) Then
Save()
End If
End Sub
Private Sub Save()
Const procName As String = "Save"
Try
_Logger.SendLog(Me.Name & "." & procName & " - Saving alarm definition data.", NLog.LogLevel.Trace)
_myAlarmDefinitionMngr.Save(_myDataSet)
_Logger.SendLog(Me.Name & "." & procName & " - Alarm definition data has been saved.", NLog.LogLevel.Trace)
Catch ex As Exception
MsgBox("There was a problem whilst saving your changes. Please reload the form and try again. " & vbCrLf & vbCrLf & ex.Message, MsgBoxStyle.Critical)
_Logger.SendLog(ex.Message & ". Thrown in module " & Me.Name.ToString & "." & procName, NLog.LogLevel.Error, ex)
Finally
End Try
End Sub
The client app sits on top of a relatively simple 3-tier architectural design talking to an Oracle 11 back-end, in this case comprising the elements AlarmDefinitionManager.vb, AlarmDefinitionDB.vb, AlarmDefinition.vb.
Public Function Save(ByVal myDataSet As DataSet) As Integer
Dim myOda As OracleDataAdapter
Dim myConnection As New OracleConnection
Dim myCommand As OracleCommand = Nothing
Dim myDataAdapter As OracleDataAdapter
Dim myBuilder As OracleCommandBuilder
Dim sqlStatement As String
myConnection = New OracleConnection
myConnection.ConnectionString = _connectStr
sqlStatement = "SELECT ID, LEGENDID, STATUSID, STATUSTYPEID, DIGITALSET FROM P_TBL_ALARMDEF"
If myDataSet.HasChanges Then
Try
myOda = New OracleDataAdapter(sqlStatement, myConnection)
myBuilder = New OracleCommandBuilder(myOda)
myOda.SelectCommand = New OracleCommand(sqlStatement, myConnection)
myOda.Update(myDataSet, "AlarmDefinition")
myDataSet.AcceptChanges()
myConnection.Close()
Catch ex As Exception
Throw
Finally
myCommand = Nothing
myDataAdapter = Nothing
myBuilder = Nothing
CType(myConnection, IDisposable).Dispose()
End Try
End If
End Function
My understanding of the situation is that I need to refresh the datasource in the grid, such that it reflects the changes made. In order to achieve this I wish to refresh the grid by hooking the refresh process into an event in the datagridview. However none of the events which I have tried seem to work. With each event tried thus far, I have received errors to the effect that a refresh of the datasource is not permitted from within the event. On reflection this seems logical. Is there any event associated with the datagridview which I can use to force a refresh of the datasource?
You shouldn't try to save your dataset while validating the row.
do your changes to your dataset then set your datasource to null and reattach your datasource back to the grid to force a refresh.
I personally don't like making changes to the datagrid. I prefer to edit the row outside the datagrid and send an UPDATE cmd to SQL then refresh my grid. I get more control on the changes made to the grid.
Sorted my problem. Each row change is saved directly to the database within the RowValidated event.

Controls not showing while loading form

I am trying to Load the form as
Dim f as New Form2
f.show()
The form is getting loaded but it doesnt show all the controls. I have two buttons and two text box. Both the buttons and one text box appears as transparent. The form appears like that till the current subroutine has ended.
Moreover, the form on loading shall display the text fetched from database and shall display the text (fetched again at equal interval from db) unless user explicitly closes the application. That logic also is in Form2_Load event.
How do I write the logic such that form2 displays properly and gets the text from db at regular interval.
I am creating a dictionary like application for healthcare domain. It works in two mode. One of the mode is ribbon mode, where a form is created (the form is marked as topmost) which should display the term and definition as long as application is alive. Hence you see an endless loop. Once user presses the close button or presses X, the application will close.
I was playing around with the code and moved it from Load even to shown event. However the issue persists.
Private Sub Form2_Shown(ByVal sender As Object, ByVal e As EventArgs) _
Handles MyBase.Shown
Dim myConnection As OleDbConnection = New OleDbConnection
Dim idSelected, queryGetWordDef, totalRows
Dim rowReturned, queryGetMaxID, provider, ipath, dataFile, connString As String
Dim dict() As String
Dim dr1 As OleDbDataReader
Dim dt As DataTable = New DataTable
provider = "Provider=Microsoft.ACE.OLEDB.12.0;Data Source ="
ipath = Application.StartupPath
dataFile = ipath & "\Database\database1.mdb" ' Change it to your Access Database location
connString = provider & dataFile
myConnection.ConnectionString = connString
queryGetMaxID = "SELECT ID FROM Table1"
myConnection.Open()
Dim cmd As OleDbCommand = New OleDbCommand(queryGetMaxID, myConnection)
Try
dr1 = cmd.ExecuteReader()
Catch ex As Exception
Console.WriteLine(ex.Message)
End Try
dt.Load(dr1)
totalRows = dt.Rows.Count
While True
idSelected = dt.Rows.Item(CInt(totalRows * Rnd()) + 1)(0)
queryGetWordDef = "SELECT Word & ""#"" & Meaning FROM Table1 WHERE ID = " & CStr(idSelected)
cmd = New OleDbCommand(queryGetWordDef, myConnection)
Try
rowReturned = cmd.ExecuteScalar()
Catch ex As Exception
Console.WriteLine(ex.Message)
End Try
dict = rowReturned.Split("#")
Me.txtBoxDefinition.Text = dict(1)
Me.txtBoxTerm.Text = dict(0)
Thread.Sleep(5000)
End While
End Sub
Picture of form attached for more clarity.
As mentioned, you have an infinite loop. The loop is entered before the form is completed being created.
To achieve what you are requesting you need to look at backgroundworker
You can use this in conjunction with the timer to trigger the backgrounderworker doWork() event.
The link also has an example of how to update the text on a form as well.
You have an endless loop in your Shown event handler. That code is executed on the UI thread and it never ends, so you can never do anything else on the UI thread.
Get rid of that loop altogether. If you want to do something every 5 seconds then use a Timer with an Interval of 5000.

How to Trigger Code with ComboBox Change Event

I have a created a database containing historical stock prices. On my form I have two comboboxes, ComboBox_Ticker and ComboBox_Date. When these comboboxes are filled I want to check the database and see if the respective data exists in the database. If it does I want to change the text of a label called Label_If_Present to "In Database".
My problem occurs with the change event. I want all of this to happen once I change the data in the textboxes. I have tried both the .TextChanged and .LostFocus events. The '.TextChanged' triggers the code to early and throws and error in my SQL command statement. The `.LostFocus' event doesn't do trigger my code at all.
Here is my current code:
Public databaseName As String = "G:\Programming\Nordeen Investing 3\NI3 Database.mdb"
Public con As New OleDb.OleDbConnection("PROVIDER=Microsoft.Jet.OLEDB.4.0;Data Source =" & databaseName)
Public tblName As String = "Historical_Stock_Prices"
Private Sub Change_Labels(ByVal sender As Object, ByVal e As EventArgs) Handles ComboBox_Ticker.TextChanged, ComboBox_Date.TextChanged
con.Close()
Dim dr As OleDbDataReader
con.Open()
If (File.Exists(databaseName)) Then
Dim restrictions(3) As String
restrictions(2) = tblName
Dim dbTbl As DataTable = con.GetSchema("Tables", restrictions)
If dbTbl.Rows.Count = 0 Then
Else
Dim cmd2 As New OleDb.OleDbCommand("SELECT * FROM " & tblName & " WHERE Ticker = '" & ComboBox_Ticker.Text & "' " & " AND Date1 = '" & ComboBox_Date.Text & "'", con)
dr = cmd2.ExecuteReader
If dr.Read() = 0 Then
'If record does not exist
Label_If_Present.Text = ""
Else
Label_If_Present.Text = "In Database"
End If
con.Close()
End If
Else
End If
End Sub
I have successfully implemented this concept on other forms within my project. This one is slightly different and I can't figure out why I can't get this one to work.
Handling the TextChanged event should work, however you need to set the DropDownStyle to DropDownList so that the Text property can only be a given value.
Then check to see that both comboboxes have values selected. Something like this should work:
If ComboBox_Ticker.Text <> "" AndAlso DateTime.TryParse(ComboBox_Date.Text, Nothing) Then

Refreshing a data grid view

This looks like an easy fix but I can't figure this out. I'm trying to have button click event on a subForm (NewTournament), add a record to a database, and then to notify a data grid which lists the records from the same database automatically (the grid is listed on HomeForm).
I so for am able to update the database and call upon a new window. But I can't get it to refresh that datagrid for anything. I know I'm supposed to clear the datagrid, get changes, then refill the grid. But everytime I do this, the code is NOT updating. Furthermore, I can very well see that the record is being added.
Private Sub CreateTournament_Click(sender As System.Object, e As System.EventArgs) Handles CreateTournament.Click
' Check the form for errors, if none exist.
' Create the tournament in the database, add the values where needed. Close the form when done.
Dim cn As OleDbConnection
Dim cmd, cmd1 As OleDbCommand
Dim icount As Integer
Dim str, str1 As String
Try
cn = New OleDbConnection("Provider=Microsoft.Jet.OLEDB.4.0;Data Source='C:\Users\Paul Williams III\Documents\Visual Studio 2010\Projects\Everything OP Client\Everything OP Client\Master.mdb'")
cn.Open()
str = "insert into Tournaments (SanctioningID,TournamentName,TournamentVenue,TournamentDateTime,TournamentFirstTable,Game,Format,OrganizerID) values(" _
& CInt(SanctioningIDTxt.Text) & ",'" & Trim(TournamentNameTxt.Text) & "','" & _
"1" & "','" & EventDateTimePck.Value & "','" & TableFirstNumberNo.Value & "','" & GameList.SelectedIndex & "','" & FormatList.SelectedIndex & "','" & Convert.ToInt32(ToIDTxt.Text) & "')"
'string stores the command and CInt is used to convert number to string
cmd = New OleDbCommand(str, cn)
str1 = "select ##Identity"
icount = cmd.ExecuteNonQuery
cmd1 = New OleDbCommand(str1, cn)
Counter = CInt(cmd1.ExecuteScalar)
MessageBox.Show(Counter & " was the last inserted id")
'displays number of records inserted
HomeForm.MasterDataSet.Clear()
HomeForm.MasterDataSet.GetChanges()
HomeForm.TournamentsTableAdapter.Fill(HomeForm.MasterDataSet.Tournaments)
HomeForm.DataGridView1.Refresh()
Catch ex As Exception
MessageBox.Show(ex.ToString)
End Try
Me.Close()
Dim n As New TournamentWindow
n.TournID = Counter
n.Show(HomeForm)
End Sub
The best approach is to add the record to the DataSource of the DataGrid. The DataGrid will automatically update. In this case its likely to be somehting like
HomeForm.MasterDataSet.Tournaments.AddTournamentsRow( CInt(SanctioningIDTxt.Text) , _
Trim(TournamentNameTxt.Text) , _
"1" , _
EventDateTimePck.Value, _
TableFirstNumberNo.Value, _
GameList.SelectedIndex, _
FormatList.SelectedIndex, _
Convert.ToInt32(ToIDTxt.Text) )
As an aside you might want to consider using parameterized queries for your Insert statement
This is my answer I hope you like it. On my project I have a switchboard and in that switchboard it contains the data grid view for my data. Before it only refresh it self when the user used the query and it will refresh it self. I taught about it how to do it different. So I used this technique the timer refresh effect. How does it work I put a timer and in the timer I copy and paste this code from the form load.
Me.ADDRESS_TICKETTableAdapter.Fill(Me.Database1DataSet.ADDRESS_TICKET)
And in the settings of the timer i turn it on and every 9 seconds it reloads the data you can change it that it reloads every 1 second if you like depends how many records it comes in. I hope this answer help you in anyway. It work for me.