DataGridView refresh problem (DataTable)

G

Guest

Hi,

I have been encountering a refresh problem with DataGridView, which is bound
to a DataTable.

When I make updates (Add, Delete, update) to the DataGridView, everything
flow nicely to DataTable. No problem here.

However, when I add data (programatically) to the DataTable, the
DataGridView does not refresh right away. If I minimize and show my form,
the new rows are now shown in my form.

Yet, when I select the new rows, the "selection triangle" is not displayed
properly on the new rows. The selection works fine with the original rows.

I made an attempt to solve the problem by using a delegate to manually
perform refresh. I solve the "non-displaying" problem, but still have the
"selection" problem.

I also notice that, as soon as I delete or cell-update a row, all these
problems go away.

Is this a bug in .Net 2.0?

Thanks,
 
G

Guest

Hi Jeffrey,

My code is similar to yours, with one exception.

You activate the DataTable.Rows.Add() from a control (button).

I have a FileSystemWatcher which detects a new input file. When a new file
appears, my code reads this file and append new data to my DataTable. Hence,
there is no interaction to the DataGridView.

I suspect the "in-activity" is causing the refresh problem. As I stated in
my first e-mail. As soon as I "interactively" delete a row, everything is
fine.

Any ideas?

Thanks,
 
J

Jeffrey Tan[MSFT]

Hi George,

Thanks for your feedback information!

Yes, I think your background information is critical regarding resolving
your problem.

FileSystemWatcher event fires in another thread other than the main GUI
thread, if you add the new row into the DataTable directly, the .Net
Winform databinding code will try to update the new row into the
DataGridView UI.
However, .Net Windows Forms uses the single-threaded apartment (STA) model
because Windows Forms is based on native Win32 windows that are inherently
apartment-threaded. The STA model implies that a window can be created on
any thread, but it cannot switch threads once created, and all function
calls to it must occur on its creation thread. So your code indirectly
manipulates the DataGridView from the non GUI thread which offends the STA
rule in .Net Winform. This may cause some strange and hard to detect
multithreading issue. Please refer to the the article below for more
information:
"Multithreaded Windows Forms Control Sample"
http://msdn.microsoft.com/library/default.asp?url=/library/en-us/cpguide/htm
l/cpconDevelopingMultithreadedWindowsFormsControl.asp

You should use Control.Invoke method to marshal the manipulating to the GUI
control from another thread. Below is my modified sample code snippet:

DataTable dt;
private void Form1_Load(object sender, EventArgs e)
{
dt = new DataTable();
dt.Columns.Add("column1", typeof(int));
dt.Columns.Add("column2", typeof(string));

for (int i = 0; i < 5; i++)
{
DataRow dr = dt.NewRow();
dr["column1"] = i;
dr["column2"] = "item" + i.ToString();
dt.Rows.Add(dr);
}
this.dataGridView1.DataSource = dt;

FileSystemWatcher fsw = new FileSystemWatcher("C:\\");
fsw.EnableRaisingEvents = true;
fsw.Created += new FileSystemEventHandler(fsw_Created);
}

void fsw_Created(object sender, FileSystemEventArgs e)
{
this.dataGridView1.Invoke(new EventHandler(button1_Click));
}

private void button1_Click(object sender, EventArgs e)
{
DataRow dr=this.dt.NewRow();
dr["column1"] = 1000;
dr["column2"] = "NewItem";
dt.Rows.Add(dr);
}

This code snippet works well on my side. If I create a new file in the
"C:\" folder, a new row will be added to the DataGridView. I have also
attached the modified project in this reply for your reference.

I hope this will resolve your problem. If you still have any problem of
resolving it, please feel free to tell me, I will work with you.

Thanks!

Best regards,
Jeffrey Tan
Microsoft Online Community Support
==================================================
When responding to posts, please "Reply to Group" via your newsreader so
that others may learn and benefit from your issue.
==================================================
This posting is provided "AS IS" with no warranties, and confers no rights.
 
G

Guest

Hi Jeffrey,

Thanks, your suggestion works. I no longer needs to manually refresh or
ResetBindings the DataGridView.

I have some additional questions/comments though. Questions first.

Q. Should I wrap all readonly, read-write and write calls to DataTable
(bounded source) and use Control.Invoke to ensure UI thread is used? For
example, DataTable.Rows[index] could be read only, or write.
DataTable.Update() may cause changes. How far should I go?

Comment: Wrapping these calls become very cumbersome, and potentially a
bottle neck since UI thread may be bogged down by work. Does Microsoft plan
to make Data bound control such as DataGridView, multi-thread safe?

Thanks,
 
G

Guest

Jeffrey,

DataTable.Update(), I meant DataAdapter.Update(DataTable). This potentially
changes DataTable.

Thanks,
--
George


George said:
Hi Jeffrey,

Thanks, your suggestion works. I no longer needs to manually refresh or
ResetBindings the DataGridView.

I have some additional questions/comments though. Questions first.

Q. Should I wrap all readonly, read-write and write calls to DataTable
(bounded source) and use Control.Invoke to ensure UI thread is used? For
example, DataTable.Rows[index] could be read only, or write.
DataTable.Update() may cause changes. How far should I go?

Comment: Wrapping these calls become very cumbersome, and potentially a
bottle neck since UI thread may be bogged down by work. Does Microsoft plan
to make Data bound control such as DataGridView, multi-thread safe?

Thanks,


--
George


"Jeffrey Tan[MSFT]" said:
Sorry, forgot to attach the sample project. Here it is.

Best regards,
Jeffrey Tan
Microsoft Online Community Support
==================================================
When responding to posts, please "Reply to Group" via your newsreader so
that others may learn and benefit from your issue.
==================================================
This posting is provided "AS IS" with no warranties, and confers no rights
 
J

Jeffrey Tan[MSFT]

Hi George,

Thanks for your feedback!

1. Yes, read-only manipulation to the GUI thread also needs to be wrapped
with Control.Invoke/BeginInvoke method. Let's suppose a control is still
updating its state while you are retrieving its state, you may get an
immediate partial updated state which may appear to be incorrect.

2. To wrap these methods or properties calling, you may write a
method(let's call it WrapMethod() ) in Form class which contains all these
code, then in FileSystemWatcher thread, you can just marshal once calling
to the WrapMethod(), not marshal to all the code statements. This will save
a lot of work.

3. Yes, any operations may cause calling to the GUI thread
methods/properties need to be mashaled.

4. Yes, I see your concern, many customers have feedbacked such request
regarding .Net winform multithreading. However, this marshaling request is
not caused by .Net Winform code, it is caused by the native Win32 standard
controls. Native Win32 windows that are inherently apartment-threaded
without thread-safe build-in for legacy reason. Because .Net controls
always encapsulate the native Win32 standard controls, it is almost
impossible for .Net winform to get rid of the STA feature. Thanks for your
understanding.

Hope my comment makes sense to you.

Best regards,
Jeffrey Tan
Microsoft Online Community Support
==================================================
When responding to posts, please "Reply to Group" via your newsreader so
that others may learn and benefit from your issue.
==================================================
This posting is provided "AS IS" with no warranties, and confers no rights.
 
J

Jeffrey Tan[MSFT]

Hi George,

Does my reply make sense to you? If you have any concern, please feel free
to tell me, thanks!

Best regards,
Jeffrey Tan
Microsoft Online Community Support
==================================================
When responding to posts, please "Reply to Group" via your newsreader so
that others may learn and benefit from your issue.
==================================================
This posting is provided "AS IS" with no warranties, and confers no rights.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top