VB.NET中未关闭或未关闭的情况下在其他表单更新时如何通过主表单中的DatagridView中的BindingSource进行刷新

问题描述 投票:0回答:1

在其他表单中更新时,我尝试通过主表单中的 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文件中的代码结果,可以看到我在另一个表单更新时主表单没有更新或刷新

code result in the gif file

vb.net winforms datagridview bindingsource bindinglist
1个回答
0
投票

从编辑表单引发一个事件,向主表单发出更新信号。

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 中以显示已编辑的项目。看来您知道该怎么做。

© www.soinside.com 2019 - 2024. All rights reserved.