|
Pardon my ignorance as I am not the best in using threads. Currently on load of child form I am calling the runworkerasync method of the background worker with retrieves data and upon completion assigns dataset to grid and formats the grid.
Here is the change I have made and I am getting an error of cross thread operation.
worker1
Async in form load
do work retrieves data from database
Completed calls Worker2Async
Worker2
Async in Completed of Worker1
Do work assigns datagridview datasource to dataset containing data retrieve by worker1
Completed formats the grid
I am getting an error in Do work for Worker 2, when I call datagridview.datasource=dataset, it says cross thread operation... datagridview accessed from a different thread then the one it was created in... Any suggestions, am I doing what you suggested?
Please help
Sameer
|
|
|
|
|
You only need one worker that gets the data from the database.
The form should kick off the background worker, then format it's datagrid as appropriate on the UI thread. ANY interaction with a control MUST be done on the UI thread, not from a background worker.
When the data fetching background work finishes it's job, just the the grid's DataSource property to the data returned.
|
|
|
|
|
Thank you Dave for the guidance. I have switched my code back to your suggestion for the most part. I now have a background worker that does the following:
On form load I am calling the runworkerasync
dowork: retrieves all the data to database and assigns it to a datatable
Completed: Assigns datatable to datagridview datasource
Now I need to run a format grid function that goes through the grid and formats some cells. Where do I call that, should I call that in the completed of the worker?
Please advice
Sameer
|
|
|
|
|
Hi,
the basic idea is:
- long computations (including waiting on a database or a network...) belong in a separate thread, which could be a BackgroundWorker or a ThreadPool thread or a real Thread instance.
- manipulations of Controls (including Forms and DataGrids) need to run on the main thread
You can organize that with BackgroundWorkers, as they have two events (Progress and Completed) that always will run on the main thread; or you can get similar results with Control.Invoke
I have a little article[^] that explains more.
Luc Pattyn [Forum Guidelines] [My Articles]
The quality and detail of your question reflects on the effectiveness of the help you are likely to get.
Show formatted code inside PRE tags, and give clear symptoms when describing a problem.
|
|
|
|
|
Private StringBuilder sb=null
private void CutCopyPaste(bool Cut, bool Copy, bool Paste)
{
foreach (Form f in this.MdiChildren)
{
if (f.ContainsFocus)
{
foreach (Control c in f.Controls)
{
if (c.Focused)
{
if (c.GetType() != typeof(Label))
{
if (Cut)
{
sb.Append(c.Text);
c.Text = "";
}
else if (Copy)
sb.Append(c.Text);
else if (Paste)
c.Text = sb.ToString();
break;
}
}
}
}
}
}
private void copyToolStripMenuItem_Click(object sender, EventArgs e)
{
try
{
sb = null;
sb = new StringBuilder();
CutCopyPaste(false, true, false);
}
catch (Exception ex)
{
MessageBox.Show(ex.Message);
}
}
private void pasteToolStripMenuItem_Click(object sender, EventArgs e)
{
try
{
if (sb != null)
CutCopyPaste(false, false, true);
}
catch (Exception ex)
{
MessageBox.Show(ex.Message);
}
}
private void cutToolStripMenuItem_Click(object sender, EventArgs e)
{
try
{
sb = null;
sb = new StringBuilder();
CutCopyPaste(true, false, false);
}
catch (Exception ex)
{
MessageBox.Show(ex.Message);
}
}
It is the complete code for cut copy and paste but if we take textbox inside the container like groupbox,panel etc. its not working ...and i want also include the feature Undo and SelectAll...how can i do this...
|
|
|
|
|
Group and Panel controls have their own Collection of controls. So once you find one of these controls you have to do a foreach() to access the controls that it holds.
You can use a recursive method to access the control you are looking for, or write code to access these special cases.
My choice would be recursion since it will handle the nesting of these special cases.
|
|
|
|
|
yes u are right...how can i acess those controls that it holds...
guide me...
|
|
|
|
|
Try something like this (not tested).
public void ProcessLabel ( Control.ControlCollection c )
{
foreach ( Control control in c )
{
if ( control.Controls.Count != 0 )
ProcessLabel ( control.Controls ) ;
if ( control is Label )
{
}
}
}
Call it like
ProcessLabel ( Controls )
If you need to send more parameters, modify the method but be sure you also add them to the recursive call as well.
public void ProcessLabel ( Control.ControlCollection c, bool cut, bool copy, bool paste )
{
foreach ( Control control in c )
{
if ( control.Controls.Count != 0 )
ProcessLabel ( control.Controls, cut, copy, paste ) ;
if ( control is Label )
{
}
}
}
|
|
|
|
|
how to call this method...
processlabel(whichcontrol);
|
|
|
|
|
You can change the signature like this to add the specific label control you are interested in processing.
public void ProcessLabel ( Control.ControlCollection c, Label label )
{ foreach ( Control control in c )
{
if ( control.Controls.Count != 0 )
ProcessLabel ( control.Controls ) ;
if ( control is Label && control.Name = label.Name )
{
label.ForeColor = Color.Red ;
}
}
}
How to call this method
ProcessLabel ( Controls, myLabel )
If you need to send more parameters, modify the method but be sure you also add them to the recursive call as well.
public void ProcessLabel ( Control.ControlCollection c,
Label label,
bool cut,
bool copy,
bool paste )
{
foreach ( Control control in c )
{
if ( control.Controls.Count != 0 )
ProcessLabel ( control.Controls, label, cut, copy, paste ) ;
if ( control is Label && control.Name = label.Name )
{
label.ForeColor = Color.Red ;
}
}
}
|
|
|
|
|
I am trying But its not working...have u run this..
|
|
|
|
|
The reason it fails is because you're not doing a recursive search through the child controls of the Form. You're only looking at the top level of the controls - controls are hierarchal in nature. I would definitely recommend reworking your code to be more modular or atleast rely on a different method of finding the focused control.
One method might be hooking up a listener for the focused event on every control (assuming you don't have 1000+ controls) - see this[^].
You might also consider using the clipboard to maintain the text to be copied rather than the stringbuilder you've got - see this[^].
|
|
|
|
|
hi,
I am using following connection string but one ISAM error comes whenever I run the application.
Kindly check the mistake that, What am I doing wrong?
Thanx in Advance
(Riaz)
"Provider=Microsoft.ACE.OLEDB.12.0;Data Source="+ strDBPath +"stockmain.accdb;Jet OLEDB:Database Password=abc;SET EXCLUSIVE=OFF;");
|
|
|
|
|
|
Have you bothered to actually look at the full connection string once it got assembled?
and does strDBPath end on a backslash?
Luc Pattyn [Forum Guidelines] [My Articles]
The quality and detail of your question reflects on the effectiveness of the help you are likely to get.
Show formatted code inside PRE tags, and give clear symptoms when describing a problem.
|
|
|
|
|
Hi,
I have an checkedListBox with 7 items :
1. a
2. b
3. c
4. d
5. e
6. f
7. g
I want to limit the user to choose only two , after 2 checkbox are checked i want it to be impossible to let the user to check another checkbox until he unchecked at least one of the checkbox that been checked.
Example :
private void checkedListBox_YAxisOptions_ItemCheck(object sender, ItemCheckEventArgs e)
{
if (e.NewValue == CheckState.Checked && this.ThereIsToMuchCheckBox() )
{
checkedListBox_YAxisOptions.SetItemCheckState(e.Index, CheckState.Unchecked);
MessageBox.Show("You can't choose more then 4 options!");
}
}
With this code i have a problem because every time i have a memory overflow problem.
How can i do it?
modified on Wednesday, August 12, 2009 8:24 AM
|
|
|
|
|
Check the selecteditems.count
Bob
Ashfield Consultants Ltd
Proud to be a 2009 Code Project MVP
|
|
|
|
|
In which event and if select one how can i stop him from select another one ?
|
|
|
|
|
Hi,
Your program should handle the ItemCheck event. The ItemCheckEventArgs has three properties, CurrentValue, Index and NewValue.
NewValue is the proposed new check state of the item at Index. Typically to prevent a change of check state one would write
e.NewValue = e.CurrentValue;
[EDIT] Just seen your modified post. There is no need for SetItemCheckState which is causing the event to be fired again and again etc. Just changing the NewValue is sufficient.
Alan.
|
|
|
|
|
|
i m doin an application in which on button click i want to browse my computer and get the file path and convert it to bytes
can any one help
This code was posted by me...
|
|
|
|
|
Use the OpenFileDialog[^] to get a path then convert it to string as follows...
System.Text.ASCIIEncoding encoding = new System.Text.ASCIIEncoding();
string bytes = encoding.GetBytes("filepathhere");
Life goes very fast. Tomorrow, today is already yesterday.
|
|
|
|
|
Dear Developers..
I have created one class ,defined public property of type "TabControl"
when i am trying to serialize it ,it gives error on this statement written in my form closing event.
XmlSerializer xmlSerializer = new XmlSerializer(SerializedClass.GetType());
There was an error reflecting type "projectname"
System.InvalidOperationException: There was an error reflecting type 'System.Windows.Forms.TabControl'. ---> System.InvalidOperationException: Cannot serialize member
Please suggest me solution ASAP
Thanking you,
|
|
|
|
|
|
You are not allowed to serialize controls/Forms!
|
|
|
|