[英]DataGridView moves rows to bottom when cell is updated with Unbound data
I have a DataGridView that is styled with code and is using data from a SQLite Database我有一个带有代码样式的 DataGridView,并且正在使用 SQLite 数据库中的数据
The Database is NOT bound to the DataGridView.数据库未绑定到 DataGridView。 A number of events are triggered when I click on a row.当我单击一行时会触发许多事件。
First the Database is updated with today's date.首先数据库更新为今天的日期。
And the cell that contain's that date reflects the change.包含该日期的单元格反映了更改。
I then call a sort on the column based on the cells value.然后我根据单元格值对列进行排序。 With this code使用此代码
dgvLinks.Sort(dgvLinks.Columns(3), ListSortDirection.Ascending)
The process works as expected with no issues IF I omit these lines of code from the Sub Routine ViewSearches() that populates the DataGridView.如果我从填充 DataGridView 的子例程 ViewSearches() 中省略这些代码行,则该过程按预期工作,没有问题。
If rowCount <= 25 Then
maxRowCount = 25 - rowCount
For iA = 1 To maxRowCount
dgvLinks.Rows.Add(" ")
Next
End If
I can use these empty rows if I make a call to repopulate the DataGridView with ViewSearches()如果我使用 ViewSearches() 调用重新填充 DataGridView,我可以使用这些空行
I am trying to avoid this design as it seems like a over use of resource.我试图避免这种设计,因为它似乎过度使用资源。
The ERROR that is happening is the 4 rows that contain data are moved to the bottom of the DataGridView and above these 4 rows with data are the empty rows.发生的错误是包含数据的 4 行被移动到 DataGridView 的底部,而这 4 行的数据上方是空行。 I will post the relevant code below.我将在下面发布相关代码。
My question How can I keep the empty rows and populate DataGridView so the rows with data are at the top of the DataGridView?我的问题如何保留空行并填充 DataGridView,以便带有数据的行位于 DataGridView 的顶部?
Here is a Screen Shot after I selected LID 2. It is updated and bubbled to the bottom of the DGV.这是我选择 LID 2 后的屏幕截图。它已更新并冒泡到 DGV 的底部。
Private Sub ViewSearches()
Dim intID As Integer
Dim strChannelName As String
Dim strLinkAddress As String
Dim strLastVisit As String
Dim strLinkType As String
Dim rowCount As Integer
Dim maxRowCount As Integer
'Dim emptyStr As String = " "
Using conn As New SQLiteConnection($"Data Source = '{gv_dbName}';Version=3;")
conn.Open()
Using cmd As New SQLiteCommand("", conn)
'cmd.CommandText = "SELECT * FROM LinkTable"
' Line of CODE Above works with If statement in While rdr
'==========================================================
'cmd.CommandText = "SELECT * FROM LinkTable WHERE ytSiteType = 'News'"
cmd.CommandText = "SELECT * FROM LinkTable WHERE ytSiteType = @site"
cmd.Parameters.Add("@site", DbType.String).Value = gvSLT
Using rdr As SQLite.SQLiteDataReader = cmd.ExecuteReader
'dgvLinks.DataSource = rdr
'Statement Above use when DB is bound to dgvLinks
'=================================================
While rdr.Read()
intID = CInt((rdr("LID")))
strChannelName = rdr("ytChannelName").ToString
strLinkAddress = rdr("ytLinkAddress").ToString
strLastVisit = rdr("ytLastVisit").ToString
strLinkType = rdr("ytSiteType").ToString
'If strLinkType = gvSLT Then
dgvLinks.Rows.Add(intID, strChannelName, strLinkAddress, strLastVisit)
rowCount = rowCount + 1
'End If
End While
dgvLinks.Sort(dgvLinks.Columns(3), ListSortDirection.Ascending)
End Using
If rowCount <= 25 Then
maxRowCount = 25 - rowCount
For iA = 1 To maxRowCount
dgvLinks.Rows.Add(" ")
Next
End If
End Using
End Using
'FindEmpty()
End Sub
Click Event with Update to Database单击更新到数据库的事件
Private Sub dgvLinks_CellClick(sender As System.Object, e As System.Windows.Forms.DataGridViewCellEventArgs) Handles dgvLinks.CellClick
selRow = e.RowIndex
If e.RowIndex = -1 Then
gvalertType = "4"
frmAlert.ShowDialog()
Exit Sub
End If
'Dim col As DataGridViewColumn = Me.dgvLinks.Columns(e.ColumnIndex)
Dim row As DataGridViewRow = Me.dgvLinks.Rows(e.RowIndex)
If row.Cells(2).Value Is Nothing Then
gvalertType = "5"
frmAlert.ShowDialog()
Return
Exit Sub
ElseIf gvTxType = "View" Then
webPAGE = row.Cells(2).Value.ToString()
siteID = CInt(row.Cells(0).Value.ToString())
UpdateSiteData()
''MsgBox("Stop " & selRow)
'dgvLinks.ClearSelection()
'dgvLinks.Refresh()
'dgvLinks.RefreshEdit()
Process.Start(webPAGE)
'dgvLinks.Columns.Clear()
''dgvLinks.Rows.Clear()
''ViewSearches()
ElseIf gvTxType = "Delete" Or gvTxType = "Update" Then
gvID = CInt(row.Cells(0).Value)
gvSiteName = row.Cells(1).Value.ToString
gvSiteURL = row.Cells(2).Value.ToString
frmADE.Show()
Close()
End If
End Sub
Update Routine更新例程
Public Sub UpdateSiteData()
Dim dateToday = Date.Today
dateToday = CDate(CDate(Date.Today).ToString("M-d-yyyy"))
Using conn As New SQLiteConnection($"Data Source = '{gv_dbName}';Version=3;"),
cmd As New SQLiteCommand("UPDATE LinkTable SET ytLastVisit = @ytLastVisit WHERE LID =" & siteID, conn)
conn.Open()
cmd.Parameters.Add("@ytLastVisit", DbType.String).Value = dateToday.ToString("M-d-yyyy")
cmd.ExecuteNonQuery()
dgvLinks.Rows(selRow).Cells(3).Value = dateToday.ToString("M-d-yyyy")
'Line of code above INSERTS value in Last Visit Column at the correct ROW
'NOT needed if you reload data from the database
'=========================================================================
'dgvLinks.Refresh()
'dgvLinks.RefreshEdit()
dgvLinks.Sort(dgvLinks.Columns(3), ListSortDirection.Ascending)
End Using
End Sub
You will see a number of things I have tried commented out.你会看到一些我尝试过的东西被注释掉了。 As I said I can FIX the issue if I make a call to the ViewSearches() Sub Routine.正如我所说,如果我调用 ViewSearches() 子例程,我可以解决这个问题。
Private Sub StyleDGV()
'Sets Design of the DataGridView
'===============================
dgvLinks.DefaultCellStyle.Font = New Font("Times New Roman", 13.0F, FontStyle.Bold)
dgvLinks.ColumnCount = 4
dgvLinks.Columns(0).Width = 60 'ID
dgvLinks.Columns(1).Width = 325 'Site Name 325
dgvLinks.Columns(2).Width = 860 'Site Url 860
dgvLinks.Columns(3).Width = 154 'LastVisit 140
'Option with no blank rows increase col count to 5
'OR increase width of col(3) WHY? because the scroll bar is not showing
' TOTAL Width 1450 Height 488
'=============================
'To Set Col Header Size Mode = Enabled
'To Set Col Header Default Cell Styles DO in Properties
'dgvLinks.Columns(6).DefaultCellStyle.Format = "c"
dgvLinks.ColumnHeadersHeight = 10 'Sans Serif 'Tahoma
dgvLinks.ColumnHeadersDefaultCellStyle.Font = New Font("Sans Serif", 12.0F, FontStyle.Bold)
dgvLinks.ColumnHeadersDefaultCellStyle.ForeColor = Color.Blue
dgvLinks.DefaultCellStyle.BackColor = Color.LightGoldenrodYellow
'DGV Header Names
dgvLinks.Columns(0).Name = "LID"
dgvLinks.Columns(1).Name = "Site Name"
dgvLinks.Columns(2).Name = "Site URL"
dgvLinks.Columns(3).Name = "Last Visit"
dgvLinks.Columns(0).SortMode = DataGridViewColumnSortMode.NotSortable
dgvLinks.Columns(1).SortMode = DataGridViewColumnSortMode.NotSortable
dgvLinks.Columns(2).SortMode = DataGridViewColumnSortMode.NotSortable
dgvLinks.Columns(3).SortMode = DataGridViewColumnSortMode.NotSortable
End Sub
Any one following this question the FIX that permitted keeping the empty rows was to just omit the sort command in the Update to Database Sub Routine任何关注这个问题的人,允许保留空行的修复只是省略了更新到数据库子例程中的排序命令
As far as getting the data from the SQLite DB into the grid… you almost have it in the ViewSearches
method.至于从 SQLite 数据库中获取数据到网格中……您几乎可以在ViewSearches
方法中获得它。 The command text looks good;命令文本看起来不错; however you are using an SQLiteDataReader
.但是您使用的是SQLiteDataReader
。 This is resorting to reading the data line by line.这是诉诸于逐行读取数据。
I suggest you use the SQLiteDataAdapter
instead.我建议您改用SQLiteDataAdapter
。 With it you can get the DataTable
from the DB in one shot.有了它,您可以一次性从数据库中获取DataTable
。 First create and initialize a DataSet
, then create a new SQLiteDataAdapter
then add your command to the data adapter something like…首先创建并初始化一个DataSet
,然后创建一个新的SQLiteDataAdapter
然后将你的命令添加到数据适配器中,比如......
DataSet ds = new DataSet();
using (SQLiteDataAdapter sqlDA = new SQLiteDataAdapter()) {
conn.Open();
sqlDA.SelectCommand = cmd.CommanText;
sqlDA.Fill(ds, “tableName”);
if (ds.Tables.Count > 0) {
//return ds.Tables[“tableName”];
dgvLinks.DataSource = ds.Tables[“tableName”];
}
}
This will add a DataTable
to the DataSet
ds
called “tableName” if the query succeeded.如果查询成功,这将向DataSet
ds
添加一个名为“tableName”的DataTable
。
Then simply use that DataTable
as a DataSource
to the grid… something like…然后只需将该DataTable
用作网格的DataSource
......就像......
dgvLinks.DataSource = ds.Tables[“tableName”];
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.