私は数日前に他のスレッドからBindingListInvokeを探していましたが、vb.netで適切なソリューションを取得できませんでした。それらのほとんどは、C#ですが、理解するのが難しいと感じています。したがって、2つのフォーム(Form1とForm2)と1つのクラスを持つ小さなアプリケーションを作成しました。Form1はメインUIスレッドになり、Form2は別のスレッドで実行されます。
Form1には、(Tの)共有BindingListにバインドされたDataGrindViewとButtonがあり、ButtonをクリックするとForm2が別のスレッドにロードされます。
これがForm1コードです:
Imports System.ComponentModel
Imports System.Threading
Public Class Form1
Public Shared ListOfNames As BindingList(Of Names) = New BindingList(Of Names)
Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
DataGridView1.DataSource = ListOfNames
DataGridView1.Columns("FullName").DataPropertyName = "FullName"
End Sub
Private Sub Button1_Click_1(sender As Object, e As EventArgs) Handles Button1.Click
Dim thread As Threading.Thread = New Threading.Thread(AddressOf loadQuoteForm)
thread.SetApartmentState((ApartmentState.STA))
thread.Start()
End Sub
Private Sub loadQuoteForm()
Dim SecondForm As Form2 = New Form2
Application.Run(SecondForm)
End Sub
End Class
Form2にはボタンがあり、クリックするとNamesクラスインスタンスが作成され、その1つのプロパティが変更され、Form1.BindingList(of T)に追加されます。
Form2コードは次のとおりです。
Public Class Form2
Private Sub btnTestFromDiffTread_Click(sender As Object, e As EventArgs) Handles btnTestFromDiffTread.Click
Try
Dim myName As Names = New Names
myName.FullName = "John Peter"
Form1.ListOfNames.Add(myName)
Catch ex As Exception
MsgBox(ex.ToString)
End Try
End Sub
End Class
Imports System.ComponentModel
Public Class Names
Implements System.ComponentModel.INotifyPropertyChanged
Public Event PropertyChanged(sender As Object, e As System.ComponentModel.PropertyChangedEventArgs) Implements System.ComponentModel.INotifyPropertyChanged.PropertyChanged
Private _fullName As String
Public Property FullName() As String
Get
Return _fullName
End Get
Set(ByVal value As String)
_fullName = value
RaiseEvent PropertyChanged(Me, New PropertyChangedEventArgs("FullName"))
End Set
End Property
End Class
しかし、ご想像のとおり、Form2のボタンをクリックするとすぐに例外がスローされます:。
誰かが私がどこで呼び出すか委任するべきかを提案できますか、サンプルのVB.netコードは非常に高く評価されています
問題の原因となっているのはDataGridViewの更新です。
あなたのコメントから、DataGridViewがDataGridViewのDataSourceにバインドされているためであることがわかります。したがって、別のスレッドでこれを行う場合、このリストを更新するとクロススレッド操作が発生します。
1つの解決策は、ListOfNames
公開せず、このリストに追加できる新しい方法を用意することです。
Private Shared ListOfNames As BindingList(Of Names) = New BindingList(Of Names)
Public Sub AddNameToList(newNames As Names)
DataGridView1.BeginInvoke(Sub() ListOfNames.Add(newNames))
End Sub
この記事はインターネットから収集されたものであり、転載の際にはソースを示してください。
侵害の場合は、連絡してください[email protected]
コメントを追加