在其他表单中更新时,我尝试通过主表单中的 DatagridView 中的绑定源进行刷新,而未关闭或不在 VB.NET 中
请指导我
谢谢
autocompletdatagridview 中的代码(表单主)
Imports System.ComponentModel
Imports System.Data.OleDb
Imports Dapper
Public Class autocompledatagridview
Private dictProducts As Dictionary(Of String, ProductFinaltesting)
Private BindingSource1 As BindingSource = Nothing
Protected Overrides Sub OnLoad(e As EventArgs)
MyBase.OnLoad(e)
dictProducts = ProductFinaltestingService.GetDistinctProducts().
ToDictionary(Function(p) p.ToString(), Function(p) p)
BindingSource1 = New BindingSource With {.DataSource = New BindingList(Of ProductFinaltesting)}
DataGridView1.AutoGenerateColumns = False
DataGridView1.AllowUserToAddRows = False
DataGridView1.DataSource = BindingSource1
DataGridView1.Columns("Unit").ReadOnly = True
BindingSource1.AddNew()
End Sub
Private Sub DataGridView1_EditingControlShowing(
sender As Object,
e As DataGridViewEditingControlShowingEventArgs) Handles _
DataGridView1.EditingControlShowing
If TypeOf e.Control Is TextBox Then
Dim dgv = DirectCast(sender, DataGridView)
Dim tb = DirectCast(e.Control, TextBox)
If dgv.CurrentCell.ColumnIndex = dgv.Columns("ProductName").Index Then
If tb.AutoCompleteCustomSource.Count = 0 Then
tb.AutoCompleteSource = AutoCompleteSource.CustomSource
tb.AutoCompleteCustomSource.AddRange(dictProducts.Keys.ToArray())
End If
tb.AutoCompleteMode = AutoCompleteMode.Suggest
Else
tb.AutoCompleteMode = AutoCompleteMode.None
End If
End If
End Sub
Private Sub DataGridView1_CellValidating(
sender As Object,
e As DataGridViewCellValidatingEventArgs) _
Handles DataGridView1.CellValidating
Dim dgv = DirectCast(sender, DataGridView)
If e.ColumnIndex = dgv.Columns("ProductName").Index AndAlso
e.RowIndex <> dgv.NewRowIndex Then
Dim key As String
If dgv.IsCurrentCellInEditMode Then
Dim p = dictProducts.Values.
FirstOrDefault(Function(x) x.ProductName.
Equals(e.FormattedValue.
ToString(), StringComparison.InvariantCultureIgnoreCase))
If p IsNot Nothing Then
key = p.ToString()
Else
key = e.FormattedValue.ToString()
End If
Else
key = dgv(e.ColumnIndex, e.RowIndex).Value?.ToString().Trim()
End If
If String.IsNullOrEmpty(key) OrElse
Not dictProducts.ContainsKey(key) Then
Dim boundItem = DirectCast(dgv.Rows(e.RowIndex).DataBoundItem, ProductFinaltesting)
boundItem.Unit = Nothing
boundItem.Prp = Nothing
boundItem.Prs = Nothing
dgv.Rows(e.RowIndex).ErrorText = "Invalid Product!"
dgv.UpdateCellValue(dgv.Columns("Unit").Index, e.RowIndex)
dgv.UpdateCellValue(dgv.Columns("PRP").Index, e.RowIndex)
dgv.UpdateCellValue(dgv.Columns("PRS").Index, e.RowIndex)
e.Cancel = True
End If
End If
End Sub
Private Sub DataGridView1_CellValidated(
sender As Object,
e As DataGridViewCellEventArgs) Handles DataGridView1.CellValidated
Dim dgv = DirectCast(sender, DataGridView)
If e.ColumnIndex = dgv.Columns("ProductName").Index Then
Dim p As ProductFinaltesting = Nothing
Dim key = dgv(e.ColumnIndex, e.RowIndex).Value?.ToString().Trim()
If key Is Nothing Then Return
If dictProducts.TryGetValue(key, p) Then
Dim boundItem = TryCast(dgv.Rows(e.RowIndex).DataBoundItem, ProductFinaltesting)
If p.Unit <> boundItem.Unit And p.Prp <> boundItem.Prp And p.Prs <> boundItem.Prs Then
boundItem.Unit = p.Unit
dgv.UpdateCellValue(dgv.Columns("Unit").Index, e.RowIndex)
boundItem.Prp = p.Prp
dgv.UpdateCellValue(dgv.Columns("Prp").Index, e.RowIndex)
boundItem.Prs = p.Prs
dgv.UpdateCellValue(dgv.Columns("Prs").Index, e.RowIndex)
End If
dgv.Rows(e.RowIndex).ErrorText = Nothing
End If
End If
End Sub
Private Sub DataGridView1_CellEndEdit(
sender As Object,
e As DataGridViewCellEventArgs) Handles DataGridView1.CellEndEdit
Dim dgv = DirectCast(sender, DataGridView)
Dim src = DirectCast(dgv.DataSource, BindingSource)
If src.Count = e.RowIndex Then Return
If e.ColumnIndex = dgv.Columns("ProductName").Index Then
Dim p As ProductFinaltesting = Nothing
Dim key = dgv(e.ColumnIndex, e.RowIndex).Value?.ToString().Trim()
If key Is Nothing Then Return
If dictProducts.TryGetValue(key, p) Then
Dim boundItem = TryCast(dgv.Rows(e.RowIndex).DataBoundItem, ProductFinaltesting)
If p.Unit <> boundItem.Unit And p.Prp <> boundItem.Prp And p.Prs <> boundItem.Prs Then
boundItem.Unit = p.Unit
dgv.UpdateCellValue(dgv.Columns("Unit").Index, e.RowIndex)
boundItem.Prp = p.Prp
dgv.UpdateCellValue(dgv.Columns("Prp").Index, e.RowIndex)
boundItem.Prs = p.Prs
dgv.UpdateCellValue(dgv.Columns("Prs").Index, e.RowIndex)
End If
dgv.Rows(e.RowIndex).ErrorText = Nothing
End If
End If
End Sub
Protected Overrides Function ProcessCmdKey(ByRef msg As Message, ByVal keyData As Keys) As Boolean
If keyData = Keys.Tab AndAlso CBool(Keys.Enter) Then
If Me.DataGridView1.Rows.Count > 0 Then
If DataGridView1.CurrentRow.Index = (DataGridView1.Rows.Count - 1) Then
BindingSource1.AddNew()
End If
Else
End If
Return True
End If
Return MyBase.ProcessCmdKey(msg, keyData)
End Function
Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
Dim frm As New formproduct
frm.Show()
End Sub
End Class
Public Class ProductFinaltesting
'<Browsable(False)>
'Public Property Font As String = "☑️"
Public Property ProductName As String
Public Property Unit As String
Public Property Prp As Integer
Public Property Prs As Integer
Public Overrides Function ToString() As String
Return $"{ProductName}"
End Function
End Class
Public Class ProductFinaltestingService
Private Shared Function GetOledbConnectionString() As String
Return "Provider=Microsoft.ACE.OLEDB.12.0;
Data Source=|DataDirectory|\test04102024.accdb;
Persist Security Info=False;"
End Function
' ...
Friend Shared Function GetDistinctProducts() As IEnumerable(Of ProductFinaltesting)
Dim sql = "SELECT DISTINCT ProductName, Unit,Prp,Prs
FROM Products
ORDER BY ProductName"
Using _conn = New OleDbConnection(GetOledbConnectionString())
Return _conn.Query(Of ProductFinaltesting)(sql)
End Using
End Function
Friend Shared Function GetProducts() As IEnumerable(Of ProductFinaltesting)
Dim sql = "SELECT ProductName, Unit,Prp,Prs
FROM Products
ORDER BY ProductName"
Using _conn = New OleDbConnection(GetOledbConnectionString())
Return _conn.Query(Of ProductFinaltesting)(sql)
End Using
End Function
Public Sub UpdateProducts(ByVal Obj As ProductFinaltesting)
Dim sql = "UPDATE Products Set Unit=@Unit,Prp=@Prp,Prs=@Prs WHERE ProductName=@ProductName;"
Using _conn = New OleDbConnection(GetOledbConnectionString())
_conn.Execute(sql, New With {
Key Obj.Unit,
Key Obj.Prp,
Key Obj.Prs,
Key Obj.ProductName
})
End Using
End Sub
End Class
formproduct(另一种形式)中的代码
Imports System.ComponentModel
Public Class formproduct
Dim ProductFinaltestingService As New ProductFinaltestingService()
Private BindingSource1 As BindingSource = Nothing
Private Sub formproduct_Load(sender As Object, e As EventArgs) Handles MyBase.Load
loaddata()
End Sub
Private Sub loaddata()
BindingSource1 = New BindingSource With {.DataSource = New BindingList(Of ProductFinaltesting)(CType(ProductFinaltestingService.GetProducts(), IList(Of ProductFinaltesting)))}
DataGridView1.AutoGenerateColumns = False
DataGridView1.AllowUserToAddRows = False
DataGridView1.DataSource = BindingSource1
DataGridView1.ReadOnly = True
End Sub
Private Function GetSELECT() As ProductFinaltesting
Return If(DataGridView1.SelectedCells.Count = 0, Nothing, TryCast(DataGridView1.SelectedCells(0).OwningRow.DataBoundItem, ProductFinaltesting))
End Function
Private Sub DataGridView1_CellContentClick(sender As Object, e As DataGridViewCellEventArgs) Handles DataGridView1.CellContentClick
Dim dgv = DirectCast(sender, DataGridView)
If e.RowIndex >= 0 Then
Dim SelectDgv = GetSELECT()
txtProductname.Text = SelectDgv.ProductName
txtUnit.Text = SelectDgv.Unit
txtPrp.Text = CType(SelectDgv.Prp, String)
txtPrs.Text = CType(SelectDgv.Prs, String)
End If
End Sub
Private Sub BtnUpdate_Click(sender As Object, e As EventArgs) Handles BtnUpdate.Click
Try
Dim Prp As Integer
Integer.TryParse(txtPrp.Text, Prp)
Dim Prs As Integer
Integer.TryParse(txtPrs.Text, Prs)
ProductFinaltestingService.UpdateProducts(New ProductFinaltesting() With {
.Unit = txtUnit.Text,
.Prp = Prp,
.Prs = Prs,
.ProductName = txtProductname.Text
})
MessageBox.Show(Me, "Successfull")
loaddata()
Catch err As Exception
MessageBox.Show(Me, err.Message)
End Try
End Sub
End Class
我在文件中附上了gif文件中的代码结果,可以看到我在另一个表单更新时主表单没有更新或刷新
从编辑表单引发一个事件,向主表单发出更新信号。
在
formproduct
:
Public Event Updated(sender As Object, e As UpdatedEventArgs)
Public Class UpdatedEventArgs
Inherits EventArgs
Public ReadOnly Property Unit As String
Public ReadOnly Property ProductName As String
Public ReadOnly Property Prp As Integer
Public ReadOnly Property Prs As Integer
Public Sub New(unit As String, productName As String, prp As Integer, prs As Integer)
Me.Unit = unit
Me.ProductName = productName
Me.Prp = prp
Me.Prs = prs
End Sub
End Class
Private Sub OnUpdated(e As UpdatedEventArgs)
RaiseEvent Updated(Me, e)
End Sub
内部
formproduct.BtnUpdate_Click
:
MessageBox.Show(Me, "Successfull")
loaddata()
OnUpdated(New UpdatedEventArgs(txtUnit.text, txtProductName.Text, Prp, Prs))
内部
autocompledatagridview
:
Protected Overrides Sub OnLoad(e As EventArgs)
MyBase.OnLoad(e)
updateDataSource()
End Sub
' just to make a method that can be called from different places
Protected Sub updateDataSource()
dictProducts = ProductFinaltestingService.GetDistinctProducts().
ToDictionary(Function(p) p.ToString(), Function(p) p)
BindingSource1 = New BindingSource With {.DataSource = New BindingList(Of ProductFinaltesting)}
DataGridView1.AutoGenerateColumns = False
DataGridView1.AllowUserToAddRows = False
DataGridView1.DataSource = BindingSource1
DataGridView1.Columns("Unit").ReadOnly = True
BindingSource1.AddNew()
End Sub
Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
Dim frm As New formproduct
AddHandler frm.Updated, AddressOf frmproduct_Updated
AddHandler frm.FormClosed, Sub() RemoveHandler frm.Updated, AddressOf frmproduct_Updated
frm.Show()
End Sub
Private Sub frmproduct_Updated(sender As Object, e As formproduct.UpdatedEventArgs)
updateDataSource()
End Sub
您还可以从 UpdatedEventArgs 中获取属性并将其放回主 dgv 中以显示已编辑的项目。看来您知道该怎么做。