fill dgv in the background. - vb.net

I have a dgv filled by a sp everything created with the wizard. since filling takes about 10 seconds i wanna have this in a background using a backgroundworker. I tried:
Public Class frmStart
Delegate Sub updateDGV()
Private Sub frmStart_Load(ByVal sender As System.Object, _
ByVal e As System.EventArgs) _
Handles MyBase.Load
BackgroundWorker1.WorkerSupportsCancellation = True
BackgroundWorker1.RunWorkerAsync()
End Sub
Private Sub BackgroundWorker1_DoWork(ByVal sender As System.Object, _
ByVal e As System.ComponentModel.DoWorkEventArgs) _
Handles BackgroundWorker1.DoWork
Me.Invoke(New updateDGV(AddressOf UpdatingForm))
End Sub
Private Sub BackgroundWorker1_RunWorkerCompleted(ByVal sender As Object , _
ByVal e As System.ComponentModel.RunWorkerCompletedEventArgs) _
Handles BackgroundWorker1.RunWorkerCompleted
msgbox("Completed")
End Sub
Private Sub UpdatingForm()
Try
me.tableadapter.fill(me.dataset.table)
Catch ex As Exception
MsgBox("Error during loading the dgv")
Finally
BackgroundWorker1.CancelAsync()
End Try
End Sub
End Class
I just see the first row in the dgv. How can i fill my whole dgv in the background, where is the mistake in the code? Additionally, i would like to see a popup during the fill process with "please wait your dgv gets filled". any idea how to accomplish that?
before i modified the code i had only the following line, which was programatically created.
me.tableadapter.fill(me.dataset.table)

Your new code is identical to the initial version. Me.Invoke is forcing UpdatingForm to be executed in UI thread. You can split in 2 parts.
Private Sub BackgroundWorker1_DoWork(ByVal sender As System.Object, ByVal e As System.ComponentModel.DoWorkEventArgs) Handles BackgroundWorker1.DoWork
Me.ProductsTableAdapter.Fill(Me.NorthwindDataSet.Products)
End Sub
Private Sub BackgroundWorker1_RunWorkerCompleted(ByVal sender As Object, ByVal e As System.ComponentModel.RunWorkerCompletedEventArgs) Handles BackgroundWorker1.RunWorkerCompleted
Me.ProductsBindingSource.ResetBindings(False)
End Sub
check as well Asynchronous Data Loading using TableAdapter with Cancel Feature

Related

DragLeave doesn't get called

in my VB.Net application I am try to drag and drop a custom control. It should be dropable onto another instance of the same class. So here is the code I use:
Private Sub HandleMouseDown(ByVal sender As Object, ByVal e As MouseEventArgs) Handles Me.MouseDown
Me.DoDragDrop(Me, DragDropEffects.Copy)
End Sub
Private Sub HandleDragEnter(ByVal sender As Object, ByVal e As DragEventArgs) Handles Me.DragEnter
e.Effect = If(checkDropData(e), DragDropEffects.Copy, DragDropEffects.None)
End Sub
Private Sub HandleDragDrop(ByVal sender As Object, ByVal e As DragEventArgs) Handles Me.DragDrop
addControl(e.Data.GetData(GetType(MyControl)))
End Sub
Private Sub HandleDragLeave(ByVal sender As Object, ByVal e As DragEventArgs) Handles Me.DragLeave
Console.WriteLine("HandleDragLeave: " & sender.ToString)
End Sub
I am able to drop the control but while dragging the DragLeave event never gets called. Did I miss something?
That's very bad... I used the wrong signature but the was nothing which told me I was wrong.
I found the solution here. I used DragEventArgs instead of EventArgs as type of e. After changing the type it works like expected.

Access Main thread data from the Background thread

I´m using a backgroundworker to handle processing of data while the user is still free to for instance click another button that aborts the process.
However, the code in backgroundworker requires several pieces of data, for instance it needs to know whether a radio button is checked.
Is there a way to access data in another thread from the background thread? Or should I create global variables that hold this information?
Public Class Test
Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
Button1.Content = "Working..."
BackgroundWorker1.RunWorkerAsync()
End Sub
Private Sub BackgroundWorker1_DoWork(ByVal sender As Object, ByVal e As System.ComponentModel.DoWorkEventArgs) Handles BackgroundWorker1.DoWork
If RadioButton1.IsChecked Then
MsgBox("It works")
End If
End Sub
End Class
You can pass the RadioButton checked state to the RunWorkerAsync method like this:
Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
BackgroundWorker1.RunWorkerAsync(RadioButton1.Checked)
End Sub
Private Sub BackgroundWorker1_DoWork(sender As Object, e As System.ComponentModel.DoWorkEventArgs) Handles BackgroundWorker1.DoWork
Dim checked As Boolean = CBool(e.Argument)
If checked Then
MessageBox.Show("It works")
End If
End Sub
Let me know if you need to be checking the RadioButton continuously from inside a loop, as that would be different.

VB.NET optimizing drag & drop code

I'm currently struggling with drag & drop code. I have 3 images that are at the top, and I want to add them in a random order in a flow-layout-panel.
I have this code for adding the square image into the flow-layout-panel, but I have got the feeling that this is not 100% correct. Is it possible to add these with 1 sub instead of 3?
And how do you write a sub that detects what object in being dragged? Now my sub just adds a square with each dragdrop event. But I need it to drop a Square only when a Square is being dragged and drop a Trapezium or round when it's being dragged.
Public Class Form2
Private Sub PictureBox1_MouseMove(ByVal sender As Object, ByVal e As System.Windows.Forms.MouseEventArgs) Handles PictureBox1.MouseMove
' Initiate dragging.
PictureBox1.DoDragDrop(PictureBox1, DragDropEffects.Copy)
End Sub
Private Sub PictureBox2_MouseMove(ByVal sender As Object, ByVal e As System.Windows.Forms.MouseEventArgs) Handles PictureBox2.MouseMove
' Initiate dragging.
PictureBox2.DoDragDrop(PictureBox2, DragDropEffects.Copy)
End Sub
Private Sub PictureBox3_MouseMove(ByVal sender As Object, ByVal e As System.Windows.Forms.MouseEventArgs) Handles PictureBox3.MouseMove
' Initiate dragging.
PictureBox3.DoDragDrop(PictureBox2, DragDropEffects.Copy)
End Sub
Private Sub FlowLayoutPanel1_DragEnter(ByVal sender As Object, ByVal e As _
System.Windows.Forms.DragEventArgs) Handles FlowLayoutPanel1.DragEnter
' Check the format of the data being dropped.
If (e.Data.GetDataPresent(GetType(PictureBox))) Then
' Display the copy cursor.
e.Effect = DragDropEffects.Copy
Else
' Display the no-drop cursor.
e.Effect = DragDropEffects.None
End If
End Sub
Private Sub FlowLayoutPanel1_DragDrop(ByVal sender As Object, ByVal e As _
System.Windows.Forms.DragEventArgs) Handles FlowLayoutPanel1.DragDrop
Dim oPB As New PictureBox()
oPB.Image = Image.FromFile("C:\Users\Jef\Desktop\square.jpg")
oPB.Visible = True
oPB.Width = 100
oPB.Height = 100
oPB.SizeMode = PictureBoxSizeMode.CenterImage
FlowLayoutPanel1.Controls.Add(oPB)
End Sub
You already got the answer in your previous question:
Private Sub FlowLayoutPanel1_DragDrop(ByVal sender As Object, ByVal e As _
System.Windows.Forms.DragEventArgs) Handles FlowLayoutPanel1.DragDrop
Dim oPB As New PictureBox()
Dim pb = CType(e.Data.GetData(GetType(PictureBox)))
oPB.Image = pb.Image
pb.Image = Nothing '' Optional
'' etc...
End Sub
You do have a bug, the probable reason why you did not use the answer:
Private Sub PictureBox3_MouseMove(ByVal sender As Object, ByVal e As System.Windows.Forms.MouseEventArgs) Handles PictureBox3.MouseMove
' Initiate dragging.
PictureBox3.DoDragDrop(PictureBox2, DragDropEffects.Copy)
End Sub
Note how it drags the wrong control, PictureBox2 instead of PictureBox3. You avoid bugs like this by writing DRY code, Do not Repeat Yourself. The sender argument of a MouseMove event already gives you a reference to the control. So you just need one event handler for all three controls:
Private Sub PictureBox_MouseMove(ByVal sender As Object, ByVal e As System.Windows.Forms.MouseEventArgs) Handles PictureBox1.MouseMove, PictureBox2.MouseMove, PictureBox3.MouseMove
' Initiate dragging.
Me.DoDragDrop(sender, DragDropEffects.Copy)
End Sub
With the detail that we now let the Form support DoDragDrop(). Which only matters if you implement the GiveFeedback or QueryContinueDrag events.

Button Click Event Within Another

I have two buttons Start button and Stop button .I run my program by clicking on start button. I want to stop the program during the start button . But the program will not responde until the start buttun finish its job. How i can do check the stop buttun during the start. i heard about threading but i do not know how i can do it.
Private Sub Button_Start (ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
//my code
//check always if the user push stop if no continue if yes go to this sub
//my code
end sub
Private Sub Button_Stop (ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button3.Click
stopClick = True
Dim Response As Integer
Response = MessageBox.Show("Do you really want to exit?", "", MessageBoxButtons.YesNo, MessageBoxIcon.Question)
If Response = vbYes Then
Me.Close()
End If
End Sub
you can use threading put button1 code in a function and use the thread .
you can refer to this example
'Thread created to handle the Background process for start_function
Dim t As System.Threading.Thread
Private Sub start_function()
While True
'your code here for Eg:
Dim i As Integer
i = i + 1
End While
End Sub
Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
t = New System.Threading.Thread(AddressOf Me.start_function)
t.Start()
End Sub
Private Sub Button2_Click(sender As Object, e As EventArgs) Handles Button2.Click
t.Abort()
End Sub
Drag a backgroundworker component onto your form.
Imports System.ComponentModel
Public Class Form1
Private Sub btnStart_Click(sender As Object, e As EventArgs) Handles btnStart.Click
Me.Text = "Busy Doing Work"
BackgroundWorker1.WorkerSupportsCancellation = True
BackgroundWorker1.RunWorkerAsync()
End Sub
Private Sub btnStop_Click(sender As Object, e As EventArgs) Handles btnStop.Click
Me.Text = "Asking to Cancel"
BackgroundWorker1.CancelAsync()
End Sub
Private Sub BackgroundWorker1_DoWork(sender As Object, e As System.ComponentModel.DoWorkEventArgs) Handles BackgroundWorker1.DoWork
While Not BackgroundWorker1.CancellationPending
System.Threading.Thread.Sleep(1000)
End While
End Sub
Private Sub BackgroundWorker1_RunWorkerCompleted(sender As Object, e As System.ComponentModel.RunWorkerCompletedEventArgs) Handles BackgroundWorker1.RunWorkerCompleted
Me.Text = "Cancelled"
End Sub
End Class

Disposing background worker does not work

I have a background worker that calls a form, holding a gif animation. The purpose is to display the animation while process is underway but it should close when the process is done. But it does not close even after completion of the process. Please help.
Thanks
Private Sub BackgroundWorker1_DoWork(ByVal sender As System.Object, ByVal e As System.ComponentModel.DoWorkEventArgs) Handles BackgroundWorker1.DoWork
frmAnimation.ShowDialog()
End Sub
Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
BackgroundWorker1.RunWorkerAsync()
Dim sqldatasourceenumerator1 As SqlDataSourceEnumerator = SqlDataSourceEnumerator.Instance
datatable1 = sqldatasourceenumerator1.GetDataSources()
DataGridView1.DataSource = datatable1
'I have tried CancelAsync, but did not work
BackgroundWorker1.CancelAsync()
frmAnimation.Dispose()
End Sub
BackgroundWorkers are intended to actually do the "work" of the background operation, so the main UI thread can continue rendering things onto the screen. I suspect you want the GetDataSources() function call to be done within the BackgroundWorker thread.
Try switching what's in your button click function and what's in the DoWork function of your BackgroundWorker. Specifically, I mean something like this:
Private Sub BackgroundWorker1_DoWork(ByVal sender As System.Object, ByVal e As System.ComponentModel.DoWorkEventArgs) Handles BackgroundWorker1.DoWork
Dim sqldatasourceenumerator1 As SqlDataSourceEnumerator = SqlDataSourceEnumerator.Instance
datatable1 = sqldatasourceenumerator1.GetDataSources()
End Sub
Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
BackgroundWorker1.RunWorkerAsync()
frmAnimation.ShowDialog()
End Sub
And in addition, add some code to the RunWorkerCompleted event to handle what should be done upon completion of your background operation.
Private Sub BackgroundWorker1_RunWorkerCompleted(ByVal sender As Object, ByVal e As RunWorkerCompletedEventArgs) Handles BackgroundWorker1.RunWorkerCompleted
DataGridView1.DataSource = datatable1
frmAnimation.Close()
End Sub
You may also want to consider using frmAnimation.Show() instead of frmAnimation.ShowDialog() depending on if you want the procedure to be modal or modeless. You can read more about that here.