| Home | Forums | Reviews | Articles | Register |
![]() |
| Thread Tools | Rate Thread |
|
|
|
| |
|
=?Utf-8?B?TWFyayBSLiBEYXdzb24=?=
Guest
Posts: n/a
|
Hi Greg,
you cannot update a control from a thread that did not create the control. In your case you are adding the labels to the panel from a different thread so that is probably why it is not updating automatically. What you want to do is transfer control back to the main UI thread to update the panel, you can do this using Invoke, so inside of backgroundWorker1_DoWork, do something like: void private void backgroundWorker1_DoWork(.....) { //Update panel UpdatePanel(); } private void UpdatePanel() { if(this.panelTemp.InvokeRequired) { //being called from different thread than main UI thread, //call this function again on the main thread. this.panelTemp.Invoke(new MethodInvoker(UpdatePanel)); } else { Label label1 = new Label(); label1.Text = "Label 1 text from background thread"; label1.Location = new Point(1, 1); label1.Size = new Size(200, 35); panelTemp.Controls.Add(label1); Label label2 = new Label(); label2.Text = "Label 2 text from background thread"; label2.Location = new Point(1, 15); label2.Size = new Size(200, 35); panelTemp.Controls.Add(label2); } } Mark -- http://www.markdawson.org "Code like the person who maintains your code is a axe murdered - WHO KNOWS WHERE YOU LIVE" "Greg Larsen" wrote: > I'm trying to figure out how to modify a panel (panel1) from a > backgroundworker thread. But can't get the panel to show the new controls > added by the backgroundwork task. Here is my code. In this code there is a > panel panel1, that I populate with a lable in the foreground. Then when I > click on "button1" a backgroundworker thread in async mode is started. When > the backgoundworker thread completes the thread returns a panel to populate > the panel1 control in the form with two controls label1 and lable 2. What I > can't figure out is how to redraw the form, or panel so the two new controls > are displayed. Does anyone know how to change my code to resolve this > problem? > > Here is my code: > > using System; > using System.Collections.Generic; > using System.ComponentModel; > using System.Data; > using System.Drawing; > using System.Text; > using System.Windows.Forms; > > namespace test > { > class Form1 : Form > { > public Form1() > { > InitializeComponent(); > Label label1 = new Label(); > label1.Text = "Label 1 text from foreground thread"; > label1.Location = new Point(1, 1); > label1.Size = new Size(200, 35); > panel1.Controls.Add(label1); > > } > > private void backgroundWorker1_DoWork(object sender, DoWorkEventArgs > e) > { > // Simulate a long-running task by putting the thread > // to sleep a random number of times. Each time the > // thread wakes up, report the progress. > BackgroundWorker worker = (BackgroundWorker)sender; > System.Random rand = new Random(); > Panel panelTemp = new Panel(); > int max = rand.Next(50, 500); > for (int i = 0; i < max; i++) > { > // Cancel upon cancellation requests > if (worker.CancellationPending) > { > e.Cancel = true; > break; > } > else > { > // Sleep for 30 milliseconds > System.Threading.Thread.Sleep(30); > worker.ReportProgress((int)i * 100 / max); > } > } > // Pass up the number of iterations perform to the main thread > > Label label1 = new Label(); > label1.Text = "Label 1 text from background thread"; > label1.Location = new Point(1, 1); > label1.Size = new Size(200, 35); > panelTemp.Controls.Add(label1); > > Label label2 = new Label(); > label2.Text = "Label 2 text from background thread"; > label2.Location = new Point(1, 15); > label2.Size = new Size(200, 35); > panelTemp.Controls.Add(label2); > e.Result = panelTemp; > > } > > private void backgroundWorker1_ProgressChanged(object sender, > ProgressChangedEventArgs e) > { > backgroundProgressBar.Value = e.ProgressPercentage; > > > > } > > private void backgroundWorker1_RunWorkerCompleted(object sender, > RunWorkerCompletedEventArgs e) > { > if (e.Error != null) > MessageBox.Show( > this, > "Background processing completed with errors: " + > e.Error.Message, > "ERROR!"); > else if (e.Cancelled) > MessageBox.Show( > this, > "Background processing cancelled.", > "Cancelled"); > else > { > panel1 = (Panel)e.Result; > MessageBox.Show("Number of controls on Panel1 - " + > panel1.Controls.Count.ToString()); > panel1.Invalidate(); > panel1.Refresh(); > } > > > } > > private void button1_Click(object sender, EventArgs e) > { > // Reset progress bar > > backgroundProgressBar.Minimum = 0; > backgroundProgressBar.Maximum = 100; > backgroundProgressBar.Value = 0; > panel1.Controls.Clear(); > // Initiate asynchronous processing > backgroundWorker1.RunWorkerAsync(); > > } > > private void button2_Click(object sender, EventArgs e) > { > > // Cancel asynchronous processing > > if (backgroundWorker1.IsBusy) > backgroundWorker1.CancelAsync(); > > > } > > private System.ComponentModel.IContainer components = null; > > /// <summary> > /// Clean up any resources being used. > /// </summary> > /// <param name="disposing">true if managed resources should be > disposed; otherwise, false.</param> > protected override void Dispose(bool disposing) > { > if (disposing && (components != null)) > { > components.Dispose(); > } > base.Dispose(disposing); > } > > #region Windows Form Designer generated code > > /// <summary> > /// Required method for Designer support - do not modify > /// the contents of this method with the code editor. > /// </summary> > private void InitializeComponent() > { > this.button1 = new System.Windows.Forms.Button(); > this.button2 = new System.Windows.Forms.Button(); > this.backgroundProgressBar = new > System.Windows.Forms.ProgressBar(); > this.backgroundWorker1 = new > System.ComponentModel.BackgroundWorker(); > this.panel1 = new System.Windows.Forms.Panel(); > this.SuspendLayout(); > // > // button1 > // > this.button1.Location = new System.Drawing.Point(24, 30); > this.button1.Name = "button1"; > this.button1.Size = new System.Drawing.Size(55, 22); > this.button1.TabIndex = 0; > this.button1.Text = "button1"; > this.button1.UseVisualStyleBackColor = true; > this.button1.Click += new System.EventHandler(this.button1_Click); > // > // button2 > // > this.button2.Location = new System.Drawing.Point(136, 30); > this.button2.Name = "button2"; > this.button2.Size = new System.Drawing.Size(59, 22); > this.button2.TabIndex = 1; > this.button2.Text = "button2"; > this.button2.UseVisualStyleBackColor = true; > this.button2.Click += new System.EventHandler(this.button2_Click); > // > // backgroundProgressBar > // > this.backgroundProgressBar.Location = new > System.Drawing.Point(24, 125); > this.backgroundProgressBar.Name = "backgroundProgressBar"; > this.backgroundProgressBar.Size = new System.Drawing.Size(229, > 23); > this.backgroundProgressBar.TabIndex = 2; > // > // backgroundWorker1 > // > this.backgroundWorker1.WorkerReportsProgress = true; > this.backgroundWorker1.WorkerSupportsCancellation = true; > this.backgroundWorker1.DoWork += new > System.ComponentModel.DoWorkEventHandler(this.backgroundWorker1_DoWork); > this.backgroundWorker1.RunWorkerCompleted += new > System.ComponentModel.RunWorkerCompletedEventHandler(this.backgroundWorker1_RunWorkerCompleted); > this.backgroundWorker1.ProgressChanged += new > System.ComponentModel.ProgressChangedEventHandler(this.backgroundWorker1_ProgressChanged); > // > // panel1 > // > this.panel1.BackColor = > System.Drawing.SystemColors.ControlLightLight; > this.panel1.Location = new System.Drawing.Point(24, 177); > this.panel1.Name = "panel1"; > this.panel1.Size = new System.Drawing.Size(238, 50); > this.panel1.TabIndex = 3; > // > // Form1 > // > this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F); > this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; > this.ClientSize = new System.Drawing.Size(292, 266); > this.Controls.Add(this.panel1); > this.Controls.Add(this.backgroundProgressBar); > this.Controls.Add(this.button2); > this.Controls.Add(this.button1); > this.Name = "Form1"; > this.Text = "Form1"; > this.ResumeLayout(false); > > } > > #endregion > > private System.Windows.Forms.Button button1; > private System.Windows.Forms.Button button2; > private System.Windows.Forms.ProgressBar backgroundProgressBar; > private System.ComponentModel.BackgroundWorker backgroundWorker1; > private System.Windows.Forms.Panel panel1; > } > } > > |
|
||
|
||||
|
=?Utf-8?B?R3JlZyBMYXJzZW4=?=
Guest
Posts: n/a
|
Mark thanks for the help. But I couldn't get what you said to work. My
problem is when I added the UpdatePanel() method to may Form1 Class it couldn't find "this.panelTemp". I assume this is because it was defined in the backgroundWorker1_DoWork method. Also I will be populating a the panelTemp control in the background thread, and then I want to pass it back to the UI thread and update the panel1 control. The UI thread will never update the panel1 control directly. If you would provide me a working example where I could add those two label control from to the UI panel1 control from the backgroundWorker1_DoWork background thread that would be great. "Mark R. Dawson" wrote: > Hi Greg, > you cannot update a control from a thread that did not create the control. > In your case you are adding the labels to the panel from a different thread > so that is probably why it is not updating automatically. What you want to > do is transfer control back to the main UI thread to update the panel, you > can do this using Invoke, so inside of backgroundWorker1_DoWork, do something > like: > > void private void backgroundWorker1_DoWork(.....) > { > //Update panel > UpdatePanel(); > } > > private void UpdatePanel() > { > if(this.panelTemp.InvokeRequired) > { > //being called from different thread than main UI thread, > //call this function again on the main thread. > this.panelTemp.Invoke(new MethodInvoker(UpdatePanel)); > } > else > { > Label label1 = new Label(); > label1.Text = "Label 1 text from background thread"; > label1.Location = new Point(1, 1); > label1.Size = new Size(200, 35); > panelTemp.Controls.Add(label1); > > Label label2 = new Label(); > label2.Text = "Label 2 text from background thread"; > label2.Location = new Point(1, 15); > label2.Size = new Size(200, 35); > panelTemp.Controls.Add(label2); > } > } > > Mark > -- > http://www.markdawson.org > "Code like the person who maintains your code is a axe murdered - WHO KNOWS > WHERE YOU LIVE" > > > "Greg Larsen" wrote: > > > I'm trying to figure out how to modify a panel (panel1) from a > > backgroundworker thread. But can't get the panel to show the new controls > > added by the backgroundwork task. Here is my code. In this code there is a > > panel panel1, that I populate with a lable in the foreground. Then when I > > click on "button1" a backgroundworker thread in async mode is started. When > > the backgoundworker thread completes the thread returns a panel to populate > > the panel1 control in the form with two controls label1 and lable 2. What I > > can't figure out is how to redraw the form, or panel so the two new controls > > are displayed. Does anyone know how to change my code to resolve this > > problem? > > > > Here is my code: > > > > using System; > > using System.Collections.Generic; > > using System.ComponentModel; > > using System.Data; > > using System.Drawing; > > using System.Text; > > using System.Windows.Forms; > > > > namespace test > > { > > class Form1 : Form > > { > > public Form1() > > { > > InitializeComponent(); > > Label label1 = new Label(); > > label1.Text = "Label 1 text from foreground thread"; > > label1.Location = new Point(1, 1); > > label1.Size = new Size(200, 35); > > panel1.Controls.Add(label1); > > > > } > > > > private void backgroundWorker1_DoWork(object sender, DoWorkEventArgs > > e) > > { > > // Simulate a long-running task by putting the thread > > // to sleep a random number of times. Each time the > > // thread wakes up, report the progress. > > BackgroundWorker worker = (BackgroundWorker)sender; > > System.Random rand = new Random(); > > Panel panelTemp = new Panel(); > > int max = rand.Next(50, 500); > > for (int i = 0; i < max; i++) > > { > > // Cancel upon cancellation requests > > if (worker.CancellationPending) > > { > > e.Cancel = true; > > break; > > } > > else > > { > > // Sleep for 30 milliseconds > > System.Threading.Thread.Sleep(30); > > worker.ReportProgress((int)i * 100 / max); > > } > > } > > // Pass up the number of iterations perform to the main thread > > > > Label label1 = new Label(); > > label1.Text = "Label 1 text from background thread"; > > label1.Location = new Point(1, 1); > > label1.Size = new Size(200, 35); > > panelTemp.Controls.Add(label1); > > > > Label label2 = new Label(); > > label2.Text = "Label 2 text from background thread"; > > label2.Location = new Point(1, 15); > > label2.Size = new Size(200, 35); > > panelTemp.Controls.Add(label2); > > e.Result = panelTemp; > > > > } > > > > private void backgroundWorker1_ProgressChanged(object sender, > > ProgressChangedEventArgs e) > > { > > backgroundProgressBar.Value = e.ProgressPercentage; > > > > > > > > } > > > > private void backgroundWorker1_RunWorkerCompleted(object sender, > > RunWorkerCompletedEventArgs e) > > { > > if (e.Error != null) > > MessageBox.Show( > > this, > > "Background processing completed with errors: " + > > e.Error.Message, > > "ERROR!"); > > else if (e.Cancelled) > > MessageBox.Show( > > this, > > "Background processing cancelled.", > > "Cancelled"); > > else > > { > > panel1 = (Panel)e.Result; > > MessageBox.Show("Number of controls on Panel1 - " + > > panel1.Controls.Count.ToString()); > > panel1.Invalidate(); > > panel1.Refresh(); > > } > > > > > > } > > > > private void button1_Click(object sender, EventArgs e) > > { > > // Reset progress bar > > > > backgroundProgressBar.Minimum = 0; > > backgroundProgressBar.Maximum = 100; > > backgroundProgressBar.Value = 0; > > panel1.Controls.Clear(); > > // Initiate asynchronous processing > > backgroundWorker1.RunWorkerAsync(); > > > > } > > > > private void button2_Click(object sender, EventArgs e) > > { > > > > // Cancel asynchronous processing > > > > if (backgroundWorker1.IsBusy) > > backgroundWorker1.CancelAsync(); > > > > > > } > > > > private System.ComponentModel.IContainer components = null; > > > > /// <summary> > > /// Clean up any resources being used. > > /// </summary> > > /// <param name="disposing">true if managed resources should be > > disposed; otherwise, false.</param> > > protected override void Dispose(bool disposing) > > { > > if (disposing && (components != null)) > > { > > components.Dispose(); > > } > > base.Dispose(disposing); > > } > > > > #region Windows Form Designer generated code > > > > /// <summary> > > /// Required method for Designer support - do not modify > > /// the contents of this method with the code editor. > > /// </summary> > > private void InitializeComponent() > > { > > this.button1 = new System.Windows.Forms.Button(); > > this.button2 = new System.Windows.Forms.Button(); > > this.backgroundProgressBar = new > > System.Windows.Forms.ProgressBar(); > > this.backgroundWorker1 = new > > System.ComponentModel.BackgroundWorker(); > > this.panel1 = new System.Windows.Forms.Panel(); > > this.SuspendLayout(); > > // > > // button1 > > // > > this.button1.Location = new System.Drawing.Point(24, 30); > > this.button1.Name = "button1"; > > this.button1.Size = new System.Drawing.Size(55, 22); > > this.button1.TabIndex = 0; > > this.button1.Text = "button1"; > > this.button1.UseVisualStyleBackColor = true; > > this.button1.Click += new System.EventHandler(this.button1_Click); > > // > > // button2 > > // > > this.button2.Location = new System.Drawing.Point(136, 30); > > this.button2.Name = "button2"; > > this.button2.Size = new System.Drawing.Size(59, 22); > > this.button2.TabIndex = 1; > > this.button2.Text = "button2"; > > this.button2.UseVisualStyleBackColor = true; > > this.button2.Click += new System.EventHandler(this.button2_Click); > > // > > // backgroundProgressBar > > // > > this.backgroundProgressBar.Location = new > > System.Drawing.Point(24, 125); > > this.backgroundProgressBar.Name = "backgroundProgressBar"; > > this.backgroundProgressBar.Size = new System.Drawing.Size(229, > > 23); > > this.backgroundProgressBar.TabIndex = 2; > > // > > // backgroundWorker1 > > // > > this.backgroundWorker1.WorkerReportsProgress = true; > > this.backgroundWorker1.WorkerSupportsCancellation = true; > > this.backgroundWorker1.DoWork += new > > System.ComponentModel.DoWorkEventHandler(this.backgroundWorker1_DoWork); > > this.backgroundWorker1.RunWorkerCompleted += new > > System.ComponentModel.RunWorkerCompletedEventHandler(this.backgroundWorker1_RunWorkerCompleted); > > this.backgroundWorker1.ProgressChanged += new > > System.ComponentModel.ProgressChangedEventHandler(this.backgroundWorker1_ProgressChanged); > > // > > // panel1 > > // > > this.panel1.BackColor = > > System.Drawing.SystemColors.ControlLightLight; > > this.panel1.Location = new System.Drawing.Point(24, 177); > > this.panel1.Name = "panel1"; > > this.panel1.Size = new System.Drawing.Size(238, 50); > > this.panel1.TabIndex = 3; > > // > > // Form1 > > // > > this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F); > > this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; > > this.ClientSize = new System.Drawing.Size(292, 266); > > this.Controls.Add(this.panel1); > > this.Controls.Add(this.backgroundProgressBar); > > this.Controls.Add(this.button2); > > this.Controls.Add(this.button1); > > this.Name = "Form1"; > > this.Text = "Form1"; > > this.ResumeLayout(false); > > > > } > > > > #endregion > > > > private System.Windows.Forms.Button button1; > > private System.Windows.Forms.Button button2; > > private System.Windows.Forms.ProgressBar backgroundProgressBar; > > private System.ComponentModel.BackgroundWorker backgroundWorker1; > > private System.Windows.Forms.Panel panel1; > > } > > } > > > > |
|
||
|
||||
|
=?Utf-8?B?TWFyayBSLiBEYXdzb24=?=
Guest
Posts: n/a
|
Hi Greg,
your code was creating the tempPanel but was never adding it to any control collection so it was never being shown. What you want to do is only modify the UI controls you create in the main UI thread, you can do this by calling Invoke, below is your code modified to work and will show the two labels: using System; using System.Collections.Generic; using System.ComponentModel; using System.Drawing; using System.Data; using System.Text; using System.Windows.Forms; namespace CSharpVision { public partial class VideoCanvas : UserControl { /// <summary> /// The camera that the video canvas is displaying /// </summary> private Camera camera; /// <summary> /// The image currently being displayed on the video canvas. /// </summary> private Image currentImage; /// <summary> /// Used to lock update access to the image which is currently /// to be displayed on the form. /// </summary> private readonly object imageLock = new object(); public VideoCanvas(Camera camera) { InitializeComponent(); this.camera = camera; } /// <summary> /// Gets the camera instance the VideoCanvas is displaying. /// </summary> public Camera Camera { get { return this.camera; } } //TODO:CurrentImage should only be available on //premium builds of the product /// <summary> /// Gets the image currently showing in the viewer. /// </summary> public Image CurrentImage { get { throw new NotImplementedException("Only available in the " + "premium edition of the viewer"); } } protected override void OnPaintBackground(PaintEventArgs e) { //Override this and do nothing so we don't get any flickering if (this.currentImage == null) { base.OnPaintBackground(e); } } protected override void OnPaint(PaintEventArgs e) { //TODO: Need to make sure we lock when we update the image lock (this.imageLock) { if (this.currentImage != null) { //we have an image to draw //Get the size of the image we are going to display Rectangle sourceRegion = new Rectangle( 0, 0, this.currentImage.Width, this.currentImage.Height); //Get the size of this control, this is the size we need //to scale the image to. Rectangle destinationRegion = new Rectangle( 0, 0, this.Width, this.Height); //Draw the image, scaling as necessary to fit the //whole control. e.Graphics.DrawImage(this.currentImage, destinationRegion, sourceRegion, GraphicsUnit.Pixel); } else { base.OnPaint(e); } } } } } Hope that helps Mark. -- http://www.markdawson.org "Code like the person who maintains your code is a psychotic axe murdered - WHO KNOWS WHERE YOU LIVE" "Greg Larsen" wrote: > Mark thanks for the help. But I couldn't get what you said to work. My > problem is when I added the UpdatePanel() method to may Form1 Class it > couldn't find "this.panelTemp". I assume this is because it was defined in > the backgroundWorker1_DoWork method. Also I will be populating a the > panelTemp control in the background thread, and then I want to pass it back > to the UI thread and update the panel1 control. The UI thread will never > update the panel1 control directly. If you would provide me a working > example where I could add those two label control from to the UI panel1 > control from the backgroundWorker1_DoWork background thread that would be > great. > > "Mark R. Dawson" wrote: > > > Hi Greg, > > you cannot update a control from a thread that did not create the control. > > In your case you are adding the labels to the panel from a different thread > > so that is probably why it is not updating automatically. What you want to > > do is transfer control back to the main UI thread to update the panel, you > > can do this using Invoke, so inside of backgroundWorker1_DoWork, do something > > like: > > > > void private void backgroundWorker1_DoWork(.....) > > { > > //Update panel > > UpdatePanel(); > > } > > > > private void UpdatePanel() > > { > > if(this.panelTemp.InvokeRequired) > > { > > //being called from different thread than main UI thread, > > //call this function again on the main thread. > > this.panelTemp.Invoke(new MethodInvoker(UpdatePanel)); > > } > > else > > { > > Label label1 = new Label(); > > label1.Text = "Label 1 text from background thread"; > > label1.Location = new Point(1, 1); > > label1.Size = new Size(200, 35); > > panelTemp.Controls.Add(label1); > > > > Label label2 = new Label(); > > label2.Text = "Label 2 text from background thread"; > > label2.Location = new Point(1, 15); > > label2.Size = new Size(200, 35); > > panelTemp.Controls.Add(label2); > > } > > } > > > > Mark > > -- > > http://www.markdawson.org > > "Code like the person who maintains your code is a axe murdered - WHO KNOWS > > WHERE YOU LIVE" > > > > > > "Greg Larsen" wrote: > > > > > I'm trying to figure out how to modify a panel (panel1) from a > > > backgroundworker thread. But can't get the panel to show the new controls > > > added by the backgroundwork task. Here is my code. In this code there is a > > > panel panel1, that I populate with a lable in the foreground. Then when I > > > click on "button1" a backgroundworker thread in async mode is started. When > > > the backgoundworker thread completes the thread returns a panel to populate > > > the panel1 control in the form with two controls label1 and lable 2. What I > > > can't figure out is how to redraw the form, or panel so the two new controls > > > are displayed. Does anyone know how to change my code to resolve this > > > problem? > > > > > > Here is my code: > > > > > > using System; > > > using System.Collections.Generic; > > > using System.ComponentModel; > > > using System.Data; > > > using System.Drawing; > > > using System.Text; > > > using System.Windows.Forms; > > > > > > namespace test > > > { > > > class Form1 : Form > > > { > > > public Form1() > > > { > > > InitializeComponent(); > > > Label label1 = new Label(); > > > label1.Text = "Label 1 text from foreground thread"; > > > label1.Location = new Point(1, 1); > > > label1.Size = new Size(200, 35); > > > panel1.Controls.Add(label1); > > > > > > } > > > > > > private void backgroundWorker1_DoWork(object sender, DoWorkEventArgs > > > e) > > > { > > > // Simulate a long-running task by putting the thread > > > // to sleep a random number of times. Each time the > > > // thread wakes up, report the progress. > > > BackgroundWorker worker = (BackgroundWorker)sender; > > > System.Random rand = new Random(); > > > Panel panelTemp = new Panel(); > > > int max = rand.Next(50, 500); > > > for (int i = 0; i < max; i++) > > > { > > > // Cancel upon cancellation requests > > > if (worker.CancellationPending) > > > { > > > e.Cancel = true; > > > break; > > > } > > > else > > > { > > > // Sleep for 30 milliseconds > > > System.Threading.Thread.Sleep(30); > > > worker.ReportProgress((int)i * 100 / max); > > > } > > > } > > > // Pass up the number of iterations perform to the main thread > > > > > > Label label1 = new Label(); > > > label1.Text = "Label 1 text from background thread"; > > > label1.Location = new Point(1, 1); > > > label1.Size = new Size(200, 35); > > > panelTemp.Controls.Add(label1); > > > > > > Label label2 = new Label(); > > > label2.Text = "Label 2 text from background thread"; > > > label2.Location = new Point(1, 15); > > > label2.Size = new Size(200, 35); > > > panelTemp.Controls.Add(label2); > > > e.Result = panelTemp; > > > > > > } > > > > > > private void backgroundWorker1_ProgressChanged(object sender, > > > ProgressChangedEventArgs e) > > > { > > > backgroundProgressBar.Value = e.ProgressPercentage; > > > > > > > > > > > > } > > > > > > private void backgroundWorker1_RunWorkerCompleted(object sender, > > > RunWorkerCompletedEventArgs e) > > > { > > > if (e.Error != null) > > > MessageBox.Show( > > > this, > > > "Background processing completed with errors: " + > > > e.Error.Message, > > > "ERROR!"); > > > else if (e.Cancelled) > > > MessageBox.Show( > > > this, > > > "Background processing cancelled.", > > > "Cancelled"); > > > else > > > { > > > panel1 = (Panel)e.Result; > > > MessageBox.Show("Number of controls on Panel1 - " + > > > panel1.Controls.Count.ToString()); > > > panel1.Invalidate(); > > > panel1.Refresh(); > > > } > > > > > > > > > } > > > > > > private void button1_Click(object sender, EventArgs e) > > > { > > > // Reset progress bar > > > > > > backgroundProgressBar.Minimum = 0; > > > backgroundProgressBar.Maximum = 100; > > > backgroundProgressBar.Value = 0; > > > panel1.Controls.Clear(); > > > // Initiate asynchronous processing > > > backgroundWorker1.RunWorkerAsync(); > > > > > > } > > > > > > private void button2_Click(object sender, EventArgs e) > > > { > > > > > > // Cancel asynchronous processing > > > > > > if (backgroundWorker1.IsBusy) > > > backgroundWorker1.CancelAsync(); > > > > > > > > > } > > > > > > private System.ComponentModel.IContainer components = null; > > > > > > /// <summary> > > > /// Clean up any resources being used. > > > /// </summary> > > > /// <param name="disposing">true if managed resources should be > > > disposed; otherwise, false.</param> > > > protected override void Dispose(bool disposing) > > > { > > > if (disposing && (components != null)) > > > { > > > components.Dispose(); > > > } > > > base.Dispose(disposing); > > > } > > > > > > #region Windows Form Designer generated code > > > > > > /// <summary> > > > /// Required method for Designer support - do not modify > > > /// the contents of this method with the code editor. > > > /// </summary> > > > private void InitializeComponent() > > > { > > > this.button1 = new System.Windows.Forms.Button(); > > > this.button2 = new System.Windows.Forms.Button(); > > > this.backgroundProgressBar = new > > > System.Windows.Forms.ProgressBar(); > > > this.backgroundWorker1 = new > > > System.ComponentModel.BackgroundWorker(); > > > this.panel1 = new System.Windows.Forms.Panel(); > > > this.SuspendLayout(); > > > // > > > // button1 > > > // > > > this.button1.Location = new System.Drawing.Point(24, 30); > > > this.button1.Name = "button1"; > > > this.button1.Size = new System.Drawing.Size(55, 22); > > > this.button1.TabIndex = 0; > > > this.button1.Text = "button1"; > > > this.button1.UseVisualStyleBackColor = true; > > > this.button1.Click += new System.EventHandler(this.button1_Click); > > > // > > > // button2 > > > // > > > this.button2.Location = new System.Drawing.Point(136, 30); > > > this.button2.Name = "button2"; > > > this.button2.Size = new System.Drawing.Size(59, 22); > > > this.button2.TabIndex = 1; > > > this.button2.Text = "button2"; > > > this.button2.UseVisualStyleBackColor = true; > > > this.button2.Click += new System.EventHandler(this.button2_Click); > > > // > > > // backgroundProgressBar > > > // > > > this.backgroundProgressBar.Location = new > > > System.Drawing.Point(24, 125); > > > this.backgroundProgressBar.Name = "backgroundProgressBar"; > > > this.backgroundProgressBar.Size = new System.Drawing.Size(229, > > > 23); > > > this.backgroundProgressBar.TabIndex = 2; > > > // > > > // backgroundWorker1 > > > // > > > this.backgroundWorker1.WorkerReportsProgress = true; > > > this.backgroundWorker1.WorkerSupportsCancellation = true; > > > this.backgroundWorker1.DoWork += new > > > System.ComponentModel.DoWorkEventHandler(this.backgroundWorker1_DoWork); > > > this.backgroundWorker1.RunWorkerCompleted += new > > > System.ComponentModel.RunWorkerCompletedEventHandler(this.backgroundWorker1_RunWorkerCompleted); > > > this.backgroundWorker1.ProgressChanged += new > > > System.ComponentModel.ProgressChangedEventHandler(this.backgroundWorker1_ProgressChanged); > > > // > > > // panel1 > > > // > > > this.panel1.BackColor = > > > System.Drawing.SystemColors.ControlLightLight; > > > this.panel1.Location = new System.Drawing.Point(24, 177); > > > this.panel1.Name = "panel1"; > > > this.panel1.Size = new System.Drawing.Size(238, 50); > > > this.panel1.TabIndex = 3; > > > // > > > // Form1 > > > // > > > this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F); > > > this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; > > > this.ClientSize = new System.Drawing.Size(292, 266); > > > this.Controls.Add(this.panel1); > > > this.Controls.Add(this.backgroundProgressBar); > > > this.Controls.Add(this.button2); > > > this.Controls.Add(this.button1); > > > this.Name = "Form1"; > > > this.Text = "Form1"; > > > this.ResumeLayout(false); > > > > > > } > > > > > > #endregion > > > > > > private System.Windows.Forms.Button button1; > > > private System.Windows.Forms.Button button2; > > > private System.Windows.Forms.ProgressBar backgroundProgressBar; > > > private System.ComponentModel.BackgroundWorker backgroundWorker1; |
|
||
|
||||
|
=?Utf-8?B?TWFyayBSLiBEYXdzb24=?=
Guest
Posts: n/a
|
Whoops, posted wrong code that is something I was working on :-)
using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; using System.Drawing; using System.Text; using System.Windows.Forms; namespace WindowsApplication1 { class Form1 : Form { public Form1() { InitializeComponent(); //Label label1 = new Label(); //label1.Text = "Label 1 text from foreground thread"; //label1.Location = new Point(1, 1); //label1.Size = new Size(200, 35); //panel1.Controls.Add(label1); } private void backgroundWorker1_DoWork(object sender, DoWorkEventArgs e) { // Simulate a long-running task by putting the thread // to sleep a random number of times. Each time the // thread wakes up, report the progress. BackgroundWorker worker = (BackgroundWorker)sender; System.Random rand = new Random(); int max = rand.Next(50, 500); for (int i = 0; i < max; i++) { // Cancel upon cancellation requests if (worker.CancellationPending) { e.Cancel = true; break; } else { // Sleep for 30 milliseconds System.Threading.Thread.Sleep(30); worker.ReportProgress((int)i * 100 / max); } } // Pass up the number of iterations perform to the main thread UpdatePanel(); } private void UpdatePanel() { if (this.InvokeRequired) { this.panel1.Invoke(new MethodInvoker(UpdatePanel)); } else { Label label1 = new Label(); label1.Text = "Label 1 text from background thread."; label1.Location = new Point(1, 1); label1.Size = new Size(200, 35); this.panel1.Controls.Add(label1); Label label2 = new Label(); label2.Text = "Label 2 text from background thread."; label2.Location = new Point(1, 35); label2.Size = new Size(200, 35); this.panel1.Controls.Add(label2); } } private void backgroundWorker1_ProgressChanged(object sender, ProgressChangedEventArgs e) { backgroundProgressBar.Value = e.ProgressPercentage; } private void backgroundWorker1_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e) { if (e.Error != null) MessageBox.Show( this, "Background processing completed with errors: " + e.Error.Message, "ERROR!"); else if (e.Cancelled) MessageBox.Show( this, "Background processing cancelled.", "Cancelled"); else { /* panel1 = (Panel)e.Result; MessageBox.Show("Number of controls on Panel1 - " + panel1.Controls.Count.ToString()); panel1.Invalidate(); panel1.Refresh(); */ } } private void button1_Click(object sender, EventArgs e) { // Reset progress bar backgroundProgressBar.Minimum = 0; backgroundProgressBar.Maximum = 100; backgroundProgressBar.Value = 0; panel1.Controls.Clear(); // Initiate asynchronous processing backgroundWorker1.RunWorkerAsync(); } private void button2_Click(object sender, EventArgs e) { // Cancel asynchronous processing if (backgroundWorker1.IsBusy) backgroundWorker1.CancelAsync(); } private System.ComponentModel.IContainer components = null; /// <summary> /// Clean up any resources being used. /// </summary> /// <param name="disposing"> /// true if managed resources should be disposed; otherwise, false.</param> protected override void Dispose(bool disposing) { if (disposing && (components != null)) { components.Dispose(); } base.Dispose(disposing); } #region Windows Form Designer generated code /// <summary> /// Required method for Designer support - do not modify /// the contents of this method with the code editor. /// </summary> private void InitializeComponent() { this.button1 = new System.Windows.Forms.Button(); this.button2 = new System.Windows.Forms.Button(); this.backgroundProgressBar = new System.Windows.Forms.ProgressBar(); this.backgroundWorker1 = new System.ComponentModel.BackgroundWorker(); this.panel1 = new System.Windows.Forms.Panel(); this.SuspendLayout(); // // button1 // this.button1.Location = new System.Drawing.Point(24, 30); this.button1.Name = "button1"; this.button1.Size = new System.Drawing.Size(55, 22); this.button1.TabIndex = 0; this.button1.Text = "button1"; this.button1.UseVisualStyleBackColor = true; this.button1.Click += new System.EventHandler(this.button1_Click); // // button2 // this.button2.Location = new System.Drawing.Point(136, 30); this.button2.Name = "button2"; this.button2.Size = new System.Drawing.Size(59, 22); this.button2.TabIndex = 1; this.button2.Text = "button2"; this.button2.UseVisualStyleBackColor = true; this.button2.Click += new System.EventHandler(this.button2_Click); // // backgroundProgressBar // this.backgroundProgressBar.Location = new System.Drawing.Point(24, 125); this.backgroundProgressBar.Name = "backgroundProgressBar"; this.backgroundProgressBar.Size = new System.Drawing.Size(229, 23); this.backgroundProgressBar.TabIndex = 2; // // backgroundWorker1 // this.backgroundWorker1.WorkerReportsProgress = true; this.backgroundWorker1.WorkerSupportsCancellation = true; this.backgroundWorker1.DoWork += new System.ComponentModel.DoWorkEventHandler(this.backgroundWorker1_DoWork); this.backgroundWorker1.RunWorkerCompleted += new System.ComponentModel.RunWorkerCompletedEventHandler(this.backgroundWorker1_RunWorkerCompleted); this.backgroundWorker1.ProgressChanged += new System.ComponentModel.ProgressChangedEventHandler(this.backgroundWorker1_ProgressChanged); // // panel1 // this.panel1.BackColor = System.Drawing.SystemColors.ControlLightLight; this.panel1.Location = new System.Drawing.Point(24, 177); this.panel1.Name = "panel1"; this.panel1.Size = new System.Drawing.Size(238, 50); this.panel1.TabIndex = 3; // // Form1 // this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F); this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; this.ClientSize = new System.Drawing.Size(292, 266); this.Controls.Add(this.panel1); this.Controls.Add(this.backgroundProgressBar); this.Controls.Add(this.button2); this.Controls.Add(this.button1); this.Name = "Form1"; this.Text = "Form1"; this.ResumeLayout(false); } #endregion private System.Windows.Forms.Button button1; private System.Windows.Forms.Button button2; private System.Windows.Forms.ProgressBar backgroundProgressBar; private System.ComponentModel.BackgroundWorker backgroundWorker1; private System.Windows.Forms.Panel panel1; } } -- http://www.markdawson.org "Code like the person who maintains your code is a psychotic axe murdered - WHO KNOWS WHERE YOU LIVE" |
|
||
|
||||
|
=?Utf-8?B?R3JlZyBMYXJzZW4=?=
Guest
Posts: n/a
|
That does the trick, but now I need to do one more thing. Is there a way
that I can pass parameters to the UpdatePanel method from the background thread? I don't seem to be able to figure that out. "Mark R. Dawson" wrote: > Whoops, posted wrong code that is something I was working on :-) > > using System; > using System.Collections.Generic; > using System.ComponentModel; > using System.Data; > using System.Drawing; > using System.Text; > using System.Windows.Forms; > > namespace WindowsApplication1 > { > class Form1 : Form > { > public Form1() > { > InitializeComponent(); > //Label label1 = new Label(); > //label1.Text = "Label 1 text from foreground thread"; > //label1.Location = new Point(1, 1); > //label1.Size = new Size(200, 35); > //panel1.Controls.Add(label1); > > } > > private void backgroundWorker1_DoWork(object sender, DoWorkEventArgs > e) > { > // Simulate a long-running task by putting the thread > // to sleep a random number of times. Each time the > // thread wakes up, report the progress. > BackgroundWorker worker = (BackgroundWorker)sender; > System.Random rand = new Random(); > int max = rand.Next(50, 500); > for (int i = 0; i < max; i++) > { > // Cancel upon cancellation requests > if (worker.CancellationPending) > { > e.Cancel = true; > break; > } > else > { > // Sleep for 30 milliseconds > System.Threading.Thread.Sleep(30); > worker.ReportProgress((int)i * 100 / max); > } > } > // Pass up the number of iterations perform to the main thread > > UpdatePanel(); > } > > private void UpdatePanel() > { > if (this.InvokeRequired) > { > this.panel1.Invoke(new MethodInvoker(UpdatePanel)); > } > else > { > Label label1 = new Label(); > label1.Text = "Label 1 text from background thread."; > label1.Location = new Point(1, 1); > label1.Size = new Size(200, 35); > this.panel1.Controls.Add(label1); > > Label label2 = new Label(); > label2.Text = "Label 2 text from background thread."; > label2.Location = new Point(1, 35); > label2.Size = new Size(200, 35); > this.panel1.Controls.Add(label2); > } > } > > > private void backgroundWorker1_ProgressChanged(object sender, > ProgressChangedEventArgs e) > { > backgroundProgressBar.Value = e.ProgressPercentage; > > > > } > > private void backgroundWorker1_RunWorkerCompleted(object sender, > RunWorkerCompletedEventArgs e) > { > if (e.Error != null) > MessageBox.Show( > this, > "Background processing completed with errors: " + > e.Error.Message, > "ERROR!"); > else if (e.Cancelled) > MessageBox.Show( > this, > "Background processing cancelled.", > "Cancelled"); > else > { > /* > panel1 = (Panel)e.Result; > MessageBox.Show("Number of controls on Panel1 - " + > panel1.Controls.Count.ToString()); > panel1.Invalidate(); > panel1.Refresh(); > */ > } > > > } > > private void button1_Click(object sender, EventArgs e) > { > // Reset progress bar > > backgroundProgressBar.Minimum = 0; > backgroundProgressBar.Maximum = 100; > backgroundProgressBar.Value = 0; > panel1.Controls.Clear(); > // Initiate asynchronous processing > backgroundWorker1.RunWorkerAsync(); > > } > > private void button2_Click(object sender, EventArgs e) > { > > // Cancel asynchronous processing > > if (backgroundWorker1.IsBusy) > backgroundWorker1.CancelAsync(); > > > } > > private System.ComponentModel.IContainer components = null; > > /// <summary> > /// Clean up any resources being used. > /// </summary> > /// <param name="disposing"> > /// true if managed resources should be disposed; otherwise, > false.</param> > protected override void Dispose(bool disposing) > { > if (disposing && (components != null)) > { > components.Dispose(); > } > base.Dispose(disposing); > } > > #region Windows Form Designer generated code > > /// <summary> > /// Required method for Designer support - do not modify > /// the contents of this method with the code editor. > /// </summary> > private void InitializeComponent() > { > this.button1 = new System.Windows.Forms.Button(); > this.button2 = new System.Windows.Forms.Button(); > this.backgroundProgressBar = new > System.Windows.Forms.ProgressBar(); > this.backgroundWorker1 = new > System.ComponentModel.BackgroundWorker(); > this.panel1 = new System.Windows.Forms.Panel(); > this.SuspendLayout(); > // > // button1 > // > this.button1.Location = new System.Drawing.Point(24, 30); > this.button1.Name = "button1"; > this.button1.Size = new System.Drawing.Size(55, 22); > this.button1.TabIndex = 0; > this.button1.Text = "button1"; > this.button1.UseVisualStyleBackColor = true; > this.button1.Click += new System.EventHandler(this.button1_Click); > // > // button2 > // > this.button2.Location = new System.Drawing.Point(136, 30); > this.button2.Name = "button2"; > this.button2.Size = new System.Drawing.Size(59, 22); > this.button2.TabIndex = 1; > this.button2.Text = "button2"; > this.button2.UseVisualStyleBackColor = true; > this.button2.Click += new System.EventHandler(this.button2_Click); > // > // backgroundProgressBar > // > this.backgroundProgressBar.Location = new > System.Drawing.Point(24, 125); > this.backgroundProgressBar.Name = "backgroundProgressBar"; > this.backgroundProgressBar.Size = new System.Drawing.Size(229, > 23); > this.backgroundProgressBar.TabIndex = 2; > // > // backgroundWorker1 > // > this.backgroundWorker1.WorkerReportsProgress = true; > this.backgroundWorker1.WorkerSupportsCancellation = true; > this.backgroundWorker1.DoWork += new > System.ComponentModel.DoWorkEventHandler(this.backgroundWorker1_DoWork); > this.backgroundWorker1.RunWorkerCompleted += new > System.ComponentModel.RunWorkerCompletedEventHandler(this.backgroundWorker1_RunWorkerCompleted); > this.backgroundWorker1.ProgressChanged += new > System.ComponentModel.ProgressChangedEventHandler(this.backgroundWorker1_ProgressChanged); > // > // panel1 > // > this.panel1.BackColor = > System.Drawing.SystemColors.ControlLightLight; > this.panel1.Location = new System.Drawing.Point(24, 177); > this.panel1.Name = "panel1"; > this.panel1.Size = new System.Drawing.Size(238, 50); > this.panel1.TabIndex = 3; > // > // Form1 > // > this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F); > this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; > this.ClientSize = new System.Drawing.Size(292, 266); > this.Controls.Add(this.panel1); > this.Controls.Add(this.backgroundProgressBar); > this.Controls.Add(this.button2); > this.Controls.Add(this.button1); > this.Name = "Form1"; > this.Text = "Form1"; > this.ResumeLayout(false); > > } > > #endregion > > private System.Windows.Forms.Button button1; > private System.Windows.Forms.Button button2; > private System.Windows.Forms.ProgressBar backgroundProgressBar; > private System.ComponentModel.BackgroundWorker backgroundWorker1; > private System.Windows.Forms.Panel panel1; > } > } > > -- > http://www.markdawson.org > "Code like the person who maintains your code is a psychotic axe murdered - > WHO KNOWS WHERE YOU LIVE" > > |
|
||
|
||||
|
=?Utf-8?B?TWFyayBSLiBEYXdzb24=?=
Guest
Posts: n/a
|
Sure, you can create your own delegate that you pass to the Invoke method,
then pass in the parameter values as an array of objects i.e. //You can put whatever parameters you want in the delegate //define this inside your form class delegate void UpdatePanelDelegate(string myParameter); //Now when you call Invoke private void UpdatePanel(string myParam) { if(this.panel1.InvokeRequired) { this.panel1.Invoke(new UpdatePanelDelegate(UpdatePanel), new object[]{myParam}); } else { //do the work using myParam } } Hope that helps. Mark. -- http://www.markdawson.org "Code like the person who maintains your code is an axe murdered - WHO KNOWS WHERE YOU LIVE" "Greg Larsen" wrote: > That does the trick, but now I need to do one more thing. Is there a way > that I can pass parameters to the UpdatePanel method from the background > thread? I don't seem to be able to figure that out. > > "Mark R. Dawson" wrote: > > > Whoops, posted wrong code that is something I was working on :-) > > > > using System; > > using System.Collections.Generic; > > using System.ComponentModel; > > using System.Data; > > using System.Drawing; > > using System.Text; > > using System.Windows.Forms; > > > > namespace WindowsApplication1 > > { > > class Form1 : Form > > { > > public Form1() > > { > > InitializeComponent(); > > //Label label1 = new Label(); > > //label1.Text = "Label 1 text from foreground thread"; > > //label1.Location = new Point(1, 1); > > //label1.Size = new Size(200, 35); > > //panel1.Controls.Add(label1); > > > > } > > > > private void backgroundWorker1_DoWork(object sender, DoWorkEventArgs > > e) > > { > > // Simulate a long-running task by putting the thread > > // to sleep a random number of times. Each time the > > // thread wakes up, report the progress. > > BackgroundWorker worker = (BackgroundWorker)sender; > > System.Random rand = new Random(); > > int max = rand.Next(50, 500); > > for (int i = 0; i < max; i++) > > { > > // Cancel upon cancellation requests > > if (worker.CancellationPending) > > { > > e.Cancel = true; > > break; > > } > > else > > { > > // Sleep for 30 milliseconds > > System.Threading.Thread.Sleep(30); > > worker.ReportProgress((int)i * 100 / max); > > } > > } > > // Pass up the number of iterations perform to the main thread > > > > UpdatePanel(); > > } > > > > private void UpdatePanel() > > { > > if (this.InvokeRequired) > > { > > this.panel1.Invoke(new MethodInvoker(UpdatePanel)); > > } > > else > > { > > Label label1 = new Label(); > > label1.Text = "Label 1 text from background thread."; > > label1.Location = new Point(1, 1); > > label1.Size = new Size(200, 35); > > this.panel1.Controls.Add(label1); > > > > Label label2 = new Label(); > > label2.Text = "Label 2 text from background thread."; > > label2.Location = new Point(1, 35); > > label2.Size = new Size(200, 35); > > this.panel1.Controls.Add(label2); > > } > > } > > > > > > private void backgroundWorker1_ProgressChanged(object sender, > > ProgressChangedEventArgs e) > > { > > backgroundProgressBar.Value = e.ProgressPercentage; > > > > > > > > } > > > > private void backgroundWorker1_RunWorkerCompleted(object sender, > > RunWorkerCompletedEventArgs e) > > { > > if (e.Error != null) > > MessageBox.Show( > > this, > > "Background processing completed with errors: " + > > e.Error.Message, > > "ERROR!"); > > else if (e.Cancelled) > > MessageBox.Show( > > this, > > "Background processing cancelled.", > > "Cancelled"); > > else > > { > > /* > > panel1 = (Panel)e.Result; > > MessageBox.Show("Number of controls on Panel1 - " + > > panel1.Controls.Count.ToString()); > > panel1.Invalidate(); > > panel1.Refresh(); > > */ > > } > > > > > > } > > > > private void button1_Click(object sender, EventArgs e) > > { > > // Reset progress bar > > > > backgroundProgressBar.Minimum = 0; > > backgroundProgressBar.Maximum = 100; > > backgroundProgressBar.Value = 0; > > panel1.Controls.Clear(); > > // Initiate asynchronous processing > > backgroundWorker1.RunWorkerAsync(); > > > > } > > > > private void button2_Click(object sender, EventArgs e) > > { > > > > // Cancel asynchronous processing > > > > if (backgroundWorker1.IsBusy) > > backgroundWorker1.CancelAsync(); > > > > > > } > > > > private System.ComponentModel.IContainer components = null; > > > > /// <summary> > > /// Clean up any resources being used. > > /// </summary> > > /// <param name="disposing"> > > /// true if managed resources should be disposed; otherwise, > > false.</param> > > protected override void Dispose(bool disposing) > > { > > if (disposing && (components != null)) > > { > > components.Dispose(); > > } > > base.Dispose(disposing); > > } > > > > #region Windows Form Designer generated code > > > > /// <summary> > > /// Required method for Designer support - do not modify > > /// the contents of this method with the code editor. > > /// </summary> > > private void InitializeComponent() > > { > > this.button1 = new System.Windows.Forms.Button(); > > this.button2 = new System.Windows.Forms.Button(); > > this.backgroundProgressBar = new > > System.Windows.Forms.ProgressBar(); > > this.backgroundWorker1 = new > > System.ComponentModel.BackgroundWorker(); > > this.panel1 = new System.Windows.Forms.Panel(); > > this.SuspendLayout(); > > // > > // button1 > > // > > this.button1.Location = new System.Drawing.Point(24, 30); > > this.button1.Name = "button1"; > > this.button1.Size = new System.Drawing.Size(55, 22); > > this.button1.TabIndex = 0; > > this.button1.Text = "button1"; > > this.button1.UseVisualStyleBackColor = true; > > this.button1.Click += new System.EventHandler(this.button1_Click); > > // > > // button2 > > // > > this.button2.Location = new System.Drawing.Point(136, 30); > > this.button2.Name = "button2"; > > this.button2.Size = new System.Drawing.Size(59, 22); > > this.button2.TabIndex = 1; > > this.button2.Text = "button2"; > > this.button2.UseVisualStyleBackColor = true; > > this.button2.Click += new System.EventHandler(this.button2_Click); > > // > > // backgroundProgressBar > > // > > this.backgroundProgressBar.Location = new > > System.Drawing.Point(24, 125); > > this.backgroundProgressBar.Name = "backgroundProgressBar"; > > this.backgroundProgressBar.Size = new System.Drawing.Size(229, > > 23); > > this.backgroundProgressBar.TabIndex = 2; > > // > > // backgroundWorker1 > > // > > this.backgroundWorker1.WorkerReportsProgress = true; > > this.backgroundWorker1.WorkerSupportsCancellation = true; > > this.backgroundWorker1.DoWork += new > > System.ComponentModel.DoWorkEventHandler(this.backgroundWorker1_DoWork); > > this.backgroundWorker1.RunWorkerCompleted += new > > System.ComponentModel.RunWorkerCompletedEventHandler(this.backgroundWorker1_RunWorkerCompleted); > > this.backgroundWorker1.ProgressChanged += new > > System.ComponentModel.ProgressChangedEventHandler(this.backgroundWorker1_ProgressChanged); > > // > > // panel1 > > // > > this.panel1.BackColor = > > System.Drawing.SystemColors.ControlLightLight; > > this.panel1.Location = new System.Drawing.Point(24, 177); > > this.panel1.Name = "panel1"; > > this.panel1.Size = new System.Drawing.Size(238, 50); > > this.panel1.TabIndex = 3; > > // > > // Form1 > > // > > this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F); > > this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; > > this.ClientSize = new System.Drawing.Size(292, 266); > > this.Controls.Add(this.panel1); > > this.Controls.Add(this.backgroundProgressBar); > > this.Controls.Add(this.button2); > > this.Controls.Add(this.button1); > > this.Name = "Form1"; > > this.Text = "Form1"; > > this.ResumeLayout(false); > > > > } > > > > #endregion > > > > private System.Windows.Forms.Button button1; > > private System.Windows.Forms.Button button2; > > private System.Windows.Forms.ProgressBar backgroundProgressBar; > > private System.ComponentModel.BackgroundWorker backgroundWorker1; > > private System.Windows.Forms.Panel panel1; > > } > > } > > > > -- > > http://www.markdawson.org > > "Code like the person who maintains your code is a psychotic axe murdered - > > WHO KNOWS WHERE YOU LIVE" > > > > |
|
||
|
||||
|
=?Utf-8?B?R3JlZyBMYXJzZW4=?=
Guest
Posts: n/a
|
I'm still having problems updating my UI panel. It seems to be blank.
Basically I populate a panel named panelTemp with controls in background thread and then issue the command below. I need to populate the controls I want in the UI panel, in the background thread because it is slow to add all the controls others otherwise. You original post worked but all the controls where added to the panel in the UI thread, and not the background thread. // call from background thread to update panel in UI UpdatePanel(panelTemp); I've defined the delegate at the top of my form like so: delegate void UpdatePanelDelegate(Panel p); And my UpdatePanel Method looks like this: private void UpdatePanel(Panel p) { if(this.panel1.InvokeRequired) { this.panel1.Invoke(new UpdatePanelDelegate(UpdatePanel), new object[]{p}); } else { panel1 = p; } } "Mark R. Dawson" wrote: > Sure, you can create your own delegate that you pass to the Invoke method, > then pass in the parameter values as an array of objects i.e. > > //You can put whatever parameters you want in the delegate > //define this inside your form class > delegate void UpdatePanelDelegate(string myParameter); > > //Now when you call Invoke > private void UpdatePanel(string myParam) > { > if(this.panel1.InvokeRequired) > { > this.panel1.Invoke(new UpdatePanelDelegate(UpdatePanel), new > object[]{myParam}); > } > else > { > //do the work using myParam > } > } > > Hope that helps. > Mark. > -- > http://www.markdawson.org > "Code like the person who maintains your code is an axe murdered - WHO KNOWS > WHERE YOU LIVE" > > > "Greg Larsen" wrote: > > > That does the trick, but now I need to do one more thing. Is there a way > > that I can pass parameters to the UpdatePanel method from the background > > thread? I don't seem to be able to figure that out. > > > > "Mark R. Dawson" wrote: > > > > > Whoops, posted wrong code that is something I was working on :-) > > > > > > using System; > > > using System.Collections.Generic; > > > using System.ComponentModel; > > > using System.Data; > > > using System.Drawing; > > > using System.Text; > > > using System.Windows.Forms; > > > > > > namespace WindowsApplication1 > > > { > > > class Form1 : Form > > > { > > > public Form1() > > > { > > > InitializeComponent(); > > > //Label label1 = new Label(); > > > //label1.Text = "Label 1 text from foreground thread"; > > > //label1.Location = new Point(1, 1); > > > //label1.Size = new Size(200, 35); > > > //panel1.Controls.Add(label1); > > > > > > } > > > > > > private void backgroundWorker1_DoWork(object sender, DoWorkEventArgs > > > e) > > > { > > > // Simulate a long-running task by putting the thread > > > // to sleep a random number of times. Each time the > > > // thread wakes up, report the progress. > > > BackgroundWorker worker = (BackgroundWorker)sender; > > > System.Random rand = new Random(); > > > int max = rand.Next(50, 500); > > > for (int i = 0; i < max; i++) > > > { > > > // Cancel upon cancellation requests > > > if (worker.CancellationPending) > > > { > > > e.Cancel = true; > > > break; > > > } > > > else > > > { > > > // Sleep for 30 milliseconds > > > System.Threading.Thread.Sleep(30); > > > worker.ReportProgress((int)i * 100 / max); > > > } > > > } > > > // Pass up the number of iterations perform to the main thread > > > > > > UpdatePanel(); > > > } > > > > > > private void UpdatePanel() > > > { > > > if (this.InvokeRequired) > > > { > > > this.panel1.Invoke(new MethodInvoker(UpdatePanel)); > > > } > > > else > > > { > > > Label label1 = new Label(); > > > label1.Text = "Label 1 text from background thread."; > > > label1.Location = new Point(1, 1); > > > label1.Size = new Size(200, 35); > > > this.panel1.Controls.Add(label1); > > > > > > Label label2 = new Label(); > > > label2.Text = "Label 2 text from background thread."; > > > label2.Location = new Point(1, 35); > > > label2.Size = new Size(200, 35); > > > this.panel1.Controls.Add(label2); > > > } > > > } > > > > > > > > > private void backgroundWorker1_ProgressChanged(object sender, > > > ProgressChangedEventArgs e) > > > { > > > backgroundProgressBar.Value = e.ProgressPercentage; > > > > > > > > > > > > } > > > > > > private void backgroundWorker1_RunWorkerCompleted(object sender, > > > RunWorkerCompletedEventArgs e) > > > { > > > if (e.Error != null) > > > MessageBox.Show( > > > this, > > > "Background processing completed with errors: " + > > > e.Error.Message, > > > "ERROR!"); > > > else if (e.Cancelled) > > > MessageBox.Show( > > > this, > > > "Background processing cancelled.", > > > "Cancelled"); > > > else > > > { > > > /* > > > panel1 = (Panel)e.Result; > > > MessageBox.Show("Number of controls on Panel1 - " + > > > panel1.Controls.Count.ToString()); > > > panel1.Invalidate(); > > > panel1.Refresh(); > > > */ > > > } > > > > > > > > > } > > > > > > private void button1_Click(object sender, EventArgs e) > > > { > > > // Reset progress bar > > > > > > backgroundProgressBar.Minimum = 0; > > > backgroundProgressBar.Maximum = 100; > > > backgroundProgressBar.Value = 0; > > > panel1.Controls.Clear(); > > > // Initiate asynchronous processing > > > backgroundWorker1.RunWorkerAsync(); > > > > > > } > > > > > > private void button2_Click(object sender, EventArgs e) > > > { > > > > > > // Cancel asynchronous processing > > > > > > if (backgroundWorker1.IsBusy) > > > backgroundWorker1.CancelAsync(); > > > > > > > > > } > > > > > > private System.ComponentModel.IContainer components = null; > > > > > > /// <summary> > > > /// Clean up any resources being used. > > > /// </summary> > > > /// <param name="disposing"> > > > /// true if managed resources should be disposed; otherwise, > > > false.</param> > > > protected override void Dispose(bool disposing) > > > { > > > if (disposing && (components != null)) > > > { > > > components.Dispose(); > > > } > > > base.Dispose(disposing); > > > } > > > > > > #region Windows Form Designer generated code > > > > > > /// <summary> > > > /// Required method for Designer support - do not modify > > > /// the contents of this method with the code editor. > > > /// </summary> > > > private void InitializeComponent() > > > { > > > this.button1 = new System.Windows.Forms.Button(); > > > this.button2 = new System.Windows.Forms.Button(); > > > this.backgroundProgressBar = new > > > System.Windows.Forms.ProgressBar(); > > > this.backgroundWorker1 = new > > > System.ComponentModel.BackgroundWorker(); > > > this.panel1 = new System.Windows.Forms.Panel(); > > > this.SuspendLayout(); > > > // > > > // button1 > > > // > > > this.button1.Location = new System.Drawing.Point(24, 30); > > > this.button1.Name = "button1"; > > > this.button1.Size = new System.Drawing.Size(55, 22); > > > this.button1.TabIndex = 0; > > > this.button1.Text = "button1"; > > > this.button1.UseVisualStyleBackColor = true; > > > this.button1.Click += new System.EventHandler(this.button1_Click); > > > // > > > // button2 > > > // > > > this.button2.Location = new System.Drawing.Point(136, 30); > > > this.button2.Name = "button2"; > > > this.button2.Size = new System.Drawing.Size(59, 22); > > > this.button2.TabIndex = 1; > > > this.button2.Text = "button2"; > > > this.button2.UseVisualStyleBackColor = true; > > > this.button2.Click += new System.EventHandler(this.button2_Click); > > > // > > > // backgroundProgressBar > > > // > > > this.backgroundProgressBar.Location = new > > > System.Drawing.Point(24, 125); > > > this.backgroundProgressBar.Name = "backgroundProgressBar"; > > > this.backgroundProgressBar.Size = new System.Drawing.Size(229, > > > 23); > > > this.backgroundProgressBar.TabIndex = 2; > > > // > > > // backgroundWorker1 > > > // > > > this.backgroundWorker1.WorkerReportsProgress = true; > > > this.backgroundWorker1.WorkerSupportsCancellation = true; > > > this.backgroundWorker1.DoWork += new > > > System.ComponentModel.DoWorkEventHandler(this.backgroundWorker1_DoWork); > > > this.backgroundWorker1.RunWorkerCompleted += new > > > System.ComponentModel.RunWorkerCompletedEventHandler(this.backgroundWorker1_RunWorkerCompleted); > > > this.backgroundWorker1.ProgressChanged += new > > > System.ComponentModel.ProgressChangedEventHandler(this.backgroundWorker1_ProgressChanged); > > > // > > > // panel1 > > > // > > > this.panel1.BackColor = > > > System.Drawing.SystemColors.ControlLightLight; > > > this.panel1.Location = new System.Drawing.Point(24, 177); > > > this.panel1.Name = "panel1"; > > > this.panel1.Size = new System.Drawing.Size(238, 50); > > > this.panel1.TabIndex = 3; > > > // > > > // Form1 > > > // > > > this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F); > > > this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; > > > this.ClientSize = new System.Drawing.Size(292, 266); > > > this.Controls.Add(this.panel1); > > > this.Controls.Add(this.backgroundProgressBar); > > > this.Controls.Add(this.button2); > > > this.Controls.Add(this.button1); > > > this.Name = "Form1"; > > > this.Text = "Form1"; > > > this.ResumeLayout(false); > > > > > > } > > > > > > #endregion > > > > > > private System.Windows.Forms.Button button1; > > > private System.Windows.Forms.Button button2; > > > private System.Windows.Forms.ProgressBar backgroundProgressBar; > > > private System.ComponentModel.BackgroundWorker backgroundWorker1; > > > private System.Windows.Forms.Panel panel1; > > > } > > > } > > > > > > -- > > > http://www.markdawson.org > > > "Code like the person who maintains your code is a psychotic axe murdered - > > > WHO KNOWS WHERE YOU LIVE" > > > > > > |
|
||
|
||||
|
=?Utf-8?B?TWFyayBSLiBEYXdzb24=?=
Guest
Posts: n/a
|
Hi Greg,
in the code below: private void UpdatePanel(Panel p) { if(this.panel1.InvokeRequired) { this.panel1.Invoke(new UpdatePanelDelegate(UpdatePanel), new object[]{p}); } else { panel1 = p; } } you have already added panel1 to the controls collection of the form previously, so that controls collection has a reference to the panel1 panel object. When you say "panel1 = p" you are simply updating what the panel1 variable points to but the forms control collection still is pointing to the original instance it does not get updated. There are a couple of things you can do, if you have a number of controls you want to add quickly then you can use the AddRange method, this accepts an array of controls to add to another control, calling this once with an array of all the controls you want to add will be very quick, probably doign away with the need for you trying to use the thread, for example myPanel.Controls.AddRange(...). Otherwise create the panel object in the main form, then from your background worker thread you can add the controls one by one to the panel by using the Invoke methodology, so each control is added to the panel in the main UI thread (the panel was created in the main UI thread and is just a class field), then when all of the controls have been added to the panel, you can then add the panel to the control collection of the form, at which point it will become visible. I would recommend using the AddRange method first though to see if it is fast enough. Mark. -- http://www.markdawson.org "Greg Larsen" wrote: > I'm still having problems updating my UI panel. It seems to be blank. > Basically I populate a panel named panelTemp with controls in background > thread and then issue the command below. I need to populate the controls I > want in the UI panel, in the background thread because it is slow to add all > the controls others otherwise. You original post worked but all the controls > where added to the panel in the UI thread, and not the background thread. > > // call from background thread to update panel in UI > UpdatePanel(panelTemp); > > I've defined the delegate at the top of my form like so: > delegate void UpdatePanelDelegate(Panel p); > > > And my UpdatePanel Method looks like this: > private void UpdatePanel(Panel p) > { > if(this.panel1.InvokeRequired) > { > this.panel1.Invoke(new UpdatePanelDelegate(UpdatePanel), new > object[]{p}); > } > else > { > panel1 = p; > } > } > > > > "Mark R. Dawson" wrote: > > > Sure, you can create your own delegate that you pass to the Invoke method, > > then pass in the parameter values as an array of objects i.e. > > > > //You can put whatever parameters you want in the delegate > > //define this inside your form class > > delegate void UpdatePanelDelegate(string myParameter); > > > > //Now when you call Invoke > > private void UpdatePanel(string myParam) > > { > > if(this.panel1.InvokeRequired) > > { > > this.panel1.Invoke(new UpdatePanelDelegate(UpdatePanel), new > > object[]{myParam}); > > } > > else > > { > > //do the work using myParam > > } > > } > > > > Hope that helps. > > Mark. > > -- > > http://www.markdawson.org > > "Code like the person who maintains your code is an axe murdered - WHO KNOWS > > WHERE YOU LIVE" > > > > > > "Greg Larsen" wrote: > > > > > That does the trick, but now I need to do one more thing. Is there a way > > > that I can pass parameters to the UpdatePanel method from the background > > > thread? I don't seem to be able to figure that out. > > > > > > "Mark R. Dawson" wrote: > > > > > > > Whoops, posted wrong code that is something I was working on :-) > > > > > > > > using System; > > > > using System.Collections.Generic; > > > > using System.ComponentModel; > > > > using System.Data; > > > > using System.Drawing; > > > > using System.Text; > > > > using System.Windows.Forms; > > > > > > > > namespace WindowsApplication1 > > > > { > > > > class Form1 : Form > > > > { > > > > public Form1() > > > > { > > > > InitializeComponent(); > > > > //Label label1 = new Label(); > > > > //label1.Text = "Label 1 text from foreground thread"; > > > > //label1.Location = new Point(1, 1); > > > > //label1.Size = new Size(200, 35); > > > > //panel1.Controls.Add(label1); > > > > > > > > } > > > > > > > > private void backgroundWorker1_DoWork(object sender, DoWorkEventArgs > > > > e) > > > > { > > > > // Simulate a long-running task by putting the thread > > > > // to sleep a random number of times. Each time the > > > > // thread wakes up, report the progress. > > > > BackgroundWorker worker = (BackgroundWorker)sender; > > > > System.Random rand = new Random(); > > > > int max = rand.Next(50, 500); > > > > for (int i = 0; i < max; i++) > > > > { > > > > // Cancel upon cancellation requests > > > > if (worker.CancellationPending) > > > > { > > > > e.Cancel = true; > > > > break; > > > > } > > > > else > > > > { > > > > // Sleep for 30 milliseconds > > > > System.Threading.Thread.Sleep(30); > > > > worker.ReportProgress((int)i * 100 / max); > > > > } > > > > } > > > > // Pass up the number of iterations perform to the main thread > > > > > > > > UpdatePanel(); > > > > } > > > > > > > > private void UpdatePanel() > > > > { > > > > if (this.InvokeRequired) > > > > { > > > > this.panel1.Invoke(new MethodInvoker(UpdatePanel)); > > > > } > > > > else > > > > { > > > > Label label1 = new Label(); > > > > label1.Text = "Label 1 text from background thread."; > > > > label1.Location = new Point(1, 1); > > > > label1.Size = new Size(200, 35); > > > > this.panel1.Controls.Add(label1); > > > > > > > > Label label2 = new Label(); > > > > label2.Text = "Label 2 text from background thread."; > > > > label2.Location = new Point(1, 35); > > > > label2.Size = new Size(200, 35); > > > > this.panel1.Controls.Add(label2); > > > > } > > > > } > > > > > > > > > > > > private void backgroundWorker1_ProgressChanged(object sender, > > > > ProgressChangedEventArgs e) > > > > { > > > > backgroundProgressBar.Value = e.ProgressPercentage; > > > > > > > > > > > > > > > > } > > > > > > > > private void backgroundWorker1_RunWorkerCompleted(object sender, > > > > RunWorkerCompletedEventArgs e) > > > > { > > > > if (e.Error != null) > > > > MessageBox.Show( > > > > this, > > > > "Background processing completed with errors: " + > > > > e.Error.Message, > > > > "ERROR!"); > > > > else if (e.Cancelled) > > > > MessageBox.Show( > > > > this, > > > > "Background processing cancelled.", > > > > "Cancelled"); > > > > else > > > > { > > > > /* > > > > panel1 = (Panel)e.Result; > > > > MessageBox.Show("Number of controls on Panel1 - " + > > > > panel1.Controls.Count.ToString()); > > > > panel1.Invalidate(); > > > > panel1.Refresh(); > > > > */ > > > > } > > > > > > > > > > > > } > > > > > > > > private void button1_Click(object sender, EventArgs e) > > > > { > > > > // Reset progress bar > > > > > > > > backgroundProgressBar.Minimum = 0; > > > > backgroundProgressBar.Maximum = 100; > > > > backgroundProgressBar.Value = 0; > > > > panel1.Controls.Clear(); > > > > // Initiate asynchronous processing > > > > backgroundWorker1.RunWorkerAsync(); > > > > > > > > } > > > > > > > > private void button2_Click(object sender, EventArgs e) > > > > { > > > > > > > > // Cancel asynchronous processing > > > > > > > > if (backgroundWorker1.IsBusy) > > > > backgroundWorker1.CancelAsync(); > > > > > > > > > > > > } > > > > > > > > private System.ComponentModel.IContainer components = null; > > > > > > > > /// <summary> > > > > /// Clean up any resources being used. > > > > /// </summary> > > > > /// <param name="disposing"> > > > > /// true if managed resources should be disposed; otherwise, > > > > false.</param> > > > > protected override void Dispose(bool disposing) > > > > { > > > > if (disposing && (components != null)) > > > > { > > > > components.Dispose(); > > > > } > > > > base.Dispose(disposing); > > > > } > > > > > > > > #region Windows Form Designer generated code > > > > > > > > /// <summary> > > > > /// Required method for Designer support - do not modify > > > > /// the contents of this method with the code editor. > > > > /// </summary> > > > > private void InitializeComponent() > > > > { > > > > this.button1 = new System.Windows.Forms.Button(); > > > > this.button2 = new System.Windows.Forms.Button(); > > > > this.backgroundProgressBar = new > > > > System.Windows.Forms.ProgressBar(); > > > > this.backgroundWorker1 = new > > > > System.ComponentModel.BackgroundWorker(); > > > > this.panel1 = new System.Windows.Forms.Panel(); > > > > this.SuspendLayout(); > > > > // > > > > // button1 > > > > // > > > > this.button1.Location = new System.Drawing.Point(24, 30); > > > > this.button1.Name = "button1"; > > > > this.button1.Size = new System.Drawing.Size(55, 22); > > > > this.button1.TabIndex = 0; > > > > this.button1.Text = "button1"; > > > > this.button1.UseVisualStyleBackColor = true; > > > > this.button1.Click += new System.EventHandler(this.button1_Click); > > > > // > > > > // button2 > > > > // > > > > this.button2.Location = new System.Drawing.Point(136, 30); > > > > this.button2.Name = "button2"; > > > > this.button2.Size = new System.Drawing.Size(59, 22); > > > > this.button2.TabIndex = 1; > > > > this.button2.Text = "button2"; > > > > this.button2.UseVisualStyleBackColor = true; > > > > this.button2.Click += new System.EventHandler(this.button2_Click); > > > > // > > > > // backgroundProgressBar > > > > // > > > > this.backgroundProgressBar.Location = new > > > > System.Drawing.Point(24, 125); > > > > this.backgroundProgressBar.Name = "backgroundProgressBar"; > > > > this.backgroundProgressBar.Size = new System.Drawing.Size(229, > > > > 23); > > > > this.backgroundProgressBar.TabIndex = 2; > > > > // > > > > // backgroundWorker1 > > > > // > > > > this.backgroundWorker1.WorkerReportsProgress = true; > > > > this.backgroundWorker1.WorkerSupportsCancellation = true; > > > > this.backgroundWorker1.DoWork += new > > > > System.ComponentModel.DoWorkEventHandler(this.backgroundWorker1_DoWork); > > > > this.backgroundWorker1.RunWorkerCompleted += new > > > > System.ComponentModel.RunWorkerCompletedEventHandler(this.backgroundWorker1_RunWorkerCompleted); > > > > this.backgroundWorker1.ProgressChanged += new > > > > System.ComponentModel.ProgressChangedEventHandler(this.backgroundWorker1_ProgressChanged); > > > > // > > > > // panel1 > > > > // > > > > this.panel1.BackColor = > > > > System.Drawing.SystemColors.ControlLightLight; > > > > this.panel1.Location = new System.Drawing.Point(24, 177); > > > > this.panel1.Name = "panel1"; > > > > this.panel1.Size = new System.Drawing.Size(238, 50); > > > > this.panel1.TabIndex = 3; > > > > // > > > > // Form1 > > > > // > > > > this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F); > > > > this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; > > > > this.ClientSize = new System.Drawing.Size(292, 266); > > > > this.Controls.Add(this.panel1); > > > > this.Controls.Add(this.backgroundProgressBar); > > > > this.Controls.Add(this.button2); > > > > this.Controls.Add(this.button1); > > > > this.Name = "Form1"; |
|
||
|
||||
|
|
|
| |
![]() |
| Thread Tools | |
| Rate This Thread | |
|
|
Similar Threads
|
||||
| Thread | Thread Starter | Forum | Replies | Last Post |
| Start background thread when a UI button is clicked, and Update UIbutton from background thread | Curious | Microsoft Dot NET | 0 | 31st Mar 2010 10:01 PM |
| Update UI from Background thread | RSH | Microsoft C# .NET | 4 | 16th Dec 2007 10:49 AM |
| .NET 3.0 RC1 - Update UI Thread From Background Thread | =?Utf-8?B?THVrZQ==?= | Microsoft Dot NET | 0 | 9th Sep 2006 09:16 AM |
| Difference between background thread and foreground thread | Ioannis Vranos | Microsoft VC .NET | 1 | 8th Nov 2004 08:25 AM |
| Update datagrid in background thread | Dave | Microsoft Dot NET Framework Forms | 0 | 26th Jan 2004 06:57 PM |
Powered by vBulletin®. Copyright ©2000 - 2012, Jelsoft Enterprises Ltd.
SEO by vBSEO ©2010, Crawlability, Inc. |




