Page 1 of 2
How to translate this Invoke/Delegate
Posted: Wed Aug 02, 2023 1:06 pm
by ic2
I still get lost when some code sample uses Invoke & Delegate.
I have this code:
Code: Select all
Self:oEmailDataTable := DataTable{}
Self:oEmailDataTable:Load(Self:oAdsDataReader)
After usually a few hours I get an exception when a timer based reading + refresh takes place and the DataGrid shows a red cross instead of content. A replier on
https://stackoverflow.com/questions/862 ... on-c-sharp says: "At some point you're trying to change the datasource of your datagrid at the exact same time it's painting itself on screen."
His C# sample is:
Code: Select all
dgvComputers1.DataSource = dt;
// Try replacing that by:
this.Invoke(delegate(DataTable table) { dgvComputers1.DataSource = table; }, dt);
I tried
Code: Select all
Invoke({ =>Self:oEmailDataTable:Load(Self:oAdsDataReader)})
but this gives me:
Error XS1660 Cannot convert lambda expression to type 'System.Delegate' because it is not a delegate type
I tried a few variations (also including Delegate) but I am not sure how to use this.
Can anyone give me the right syntax?
Dick
How to translate this Invoke/Delegate
Posted: Wed Aug 02, 2023 3:19 pm
by Chris
Hi Dick,
If I have understood it correctly, the c# code is defining a delegate type "on the fly" for which there is no syntax currently in X#, but defining the delegate separately should work
(following should be in two lines):
Code: Select all
DELEGATE LoadDelegate(table AS DataTable) AS VOID ... SELF:Invoke((LoadDelegate) {table AS DataTable => SELF:oEmailDataTable:Load(SELF:oAdsDataReader) })
or it should be possible to also do it without defining the delegate type, by using the predefined System.Action generic delegate:
Code: Select all
SELF:Invoke((System.Action ) {table AS DataTable => SELF:oEmailDataTable:Load(SELF:oAdsDataReader) })
How to translate this Invoke/Delegate
Posted: Wed Aug 02, 2023 4:12 pm
by ic2
Hello Chris,
Thanks for your suggestions. Unfortunately, it doesn't compile:
The first line gives this error:
Severity Code Description Project File Line Suppression State
Error XS1593 Delegate 'System.Action' does not take 1 arguments
No idea what I should do to solve that.
The second line goes wrong at the line
Severity Code Description Project File Line Suppression State
Error XS1003 Syntax error, 'END NAMESPACE' expected
Severity Code Description Project File Line Suppression State
Error XS9002 Parser: unexpected input 'Self'
The self is the self of the 2nd line but if I remove that line it will give the same error on the next line starting with self, so the problem is in the line Delegate LoadDelegate(table As DataTable) As Void
I am not sure how to change that either....
Dick
How to translate this Invoke/Delegate
Posted: Wed Aug 02, 2023 4:17 pm
by ic2
(As the Edit button does not show in the new site I'll add it as a new message: with '2nd line' I mean the 2nd option = the 2 lines)
How to translate this Invoke/Delegate
Posted: Wed Aug 02, 2023 4:23 pm
by Chris
Hi Dick,
Arghh, the web editor removed again some of the code, trying again:
Code: Select all
SELF:Invoke((System.Action ) {table AS DataTable => SELF:oEmailDataTable:Load(SELF:oAdsDataReader) })
also about the other syntax, you need to put the DELEGATE line in separate place, say before the CLASS declaration
How to translate this Invoke/Delegate
Posted: Wed Aug 02, 2023 4:24 pm
by Chris
Hi Dick,
Ok, this doesn't work, will send you the code by email
How to translate this Invoke/Delegate
Posted: Fri Aug 04, 2023 5:17 pm
by ic2
I saw that in my original post I am not "converting" the correct line. Basically this is what happens:
Self:oAdsDataReader := Self:oAdsCommand:ExecuteReader()
Self:oEmailDataTable := DataTable{}
Self:oBindingSource := BindingSource{}
Self:oBindingSource:DataSource := Self:oEmailDataTable
Self:oEmailDataTable:Load(Self:oAdsDataReader)
Self:dataGridViewEmails:DataSource := Self:oBindingSourcea
Apparently, if the line in bold apparently coincides with a Paint call, the program crashes (see call stack below). This can take minutes and sometimes a whole day but it will crash at some point. Instead of solving this, Microsoft programmers have programmed a big red cross to display in where the content of the DataGrid showed and there is no way to rebuild the grid, except restarting, making the project useless. Great.
According to a Stackoverflow post, using Invoke could solve that. Not sure it does, because I have been unable to get this Invoke working in X#. This line:
Self:Invoke((System.Action<DataTable>) {table As DataTable => Self:dataGridViewEmails:DataSource := Self:oEmailDataTable})
(replacing the bold line above) causes an exception Paramater Count mismatch. Chris suggested to add Null:
Self:Invoke((System.Action<DataTable>) {table As DataTable => Self:dataGridViewEmails:DataSource := Self:oEmailDataTable},Null)
But unfortunately that gives the same exception.
Does anyone have a suggestion how to get this working? This is a bit a black box for me and it is also quite frustrating having to spend so much time to fight design flaws in .Net.
Dick
Paint exception:
See the end of this message for details on invoking
just-in-time (JIT) debugging instead of this dialog box.
************** Exception Text **************
System.NullReferenceException: Object reference not set to an instance of an object.
at System.Windows.Forms.DataGridViewImageCell.PaintPrivate(Graphics g, Rectangle clipBounds, Rectangle cellBounds, Int32 rowIndex, DataGridViewElementStates elementState, Object formattedValue, String errorText, DataGridViewCellStyle cellStyle, DataGridViewAdvancedBorderStyle advancedBorderStyle, DataGridViewPaintParts paintParts, Boolean computeContentBounds, Boolean computeErrorIconBounds, Boolean paint)
at System.Windows.Forms.DataGridViewImageCell.Paint(Graphics graphics, Rectangle clipBounds, Rectangle cellBounds, Int32 rowIndex, DataGridViewElementStates elementState, Object value, Object formattedValue, String errorText, DataGridViewCellStyle cellStyle, DataGridViewAdvancedBorderStyle advancedBorderStyle, DataGridViewPaintParts paintParts)
at System.Windows.Forms.DataGridViewCell.PaintWork(Graphics graphics, Rectangle clipBounds, Rectangle cellBounds, Int32 rowIndex, DataGridViewElementStates cellState, DataGridViewCellStyle cellStyle, DataGridViewAdvancedBorderStyle advancedBorderStyle, DataGridViewPaintParts paintParts)
at System.Windows.Forms.DataGridViewRow.PaintCells(Graphics graphics, Rectangle clipBounds, Rectangle rowBounds, Int32 rowIndex, DataGridViewElementStates rowState, Boolean isFirstDisplayedRow, Boolean isLastVisibleRow, DataGridViewPaintParts paintParts)
at System.Windows.Forms.DataGridViewRow.Paint(Graphics graphics, Rectangle clipBounds, Rectangle rowBounds, Int32 rowIndex, DataGridViewElementStates rowState, Boolean isFirstDisplayedRow, Boolean isLastVisibleRow)
at System.Windows.Forms.DataGridView.PaintRows(Graphics g, Rectangle boundingRect, Rectangle clipRect, Boolean singleHorizontalBorderAdded)
at System.Windows.Forms.DataGridView.PaintGrid(Graphics g, Rectangle gridBounds, Rectangle clipRect, Boolean singleVerticalBorderAdded, Boolean singleHorizontalBorderAdded)
at System.Windows.Forms.DataGridView.OnPaint(PaintEventArgs e)
at System.Windows.Forms.Control.PaintWithErrorHandling(PaintEventArgs e, Int16 layer)
at System.Windows.Forms.Control.WmPaint(Message& m)
at System.Windows.Forms.Control.WndProc(Message& m)
at System.Windows.Forms.DataGridView.WndProc(Message& m)
at System.Windows.Forms.Control.ControlNativeWindow.OnMessage(Message& m)
at System.Windows.Forms.Control.ControlNativeWindow.WndProc(Message& m)
at System.Windows.Forms.NativeWindow.Callback(IntPtr hWnd, Int32 msg, IntPtr wparam, IntPtr lparam)
How to translate this Invoke/Delegate
Posted: Fri Aug 04, 2023 11:21 pm
by Chris
Hi DIck,
It's not for that line of code that I suggested doing that. For this one, this X# code should work:
Code: Select all
SELF:Invoke((System.Action) { => SELF:dataGridViewEmails:DataSource := SELF:oEmailDataTable})
Code: Select all
but I really doubt this will have an effect on the painting problem you see. Let's hope I am wrong though!
How to translate this Invoke/Delegate
Posted: Sat Aug 05, 2023 2:21 pm
by ic2
Hello Chris,
Yes! The line works without the parameter;sorry I started with the wrong line. Thank you so much.
In a while I will know if the paint problem is solved. If I really would not have an idea how to solve this. One would say that there must be more users using the .Net Datagrid and assigning a Datasource to it. I can't imagine that the help file of all the products explain users they have to restart their program at least once a day because their some unsolved issue with painting the grid while assigning a datasource for the last 10 years or so.
Dick
How to translate this Invoke/Delegate
Posted: Sat Aug 05, 2023 3:18 pm
by Chris
Hi Dick,
But what you are doing is not just assigning a datasource to the grid, but changing the datasource while it is possibly currently using the already assigned one, to update its contents, if I have understood your previous messages (and the stack overflow suggestion that you mentioned) correctly. Why are you assigning the datasource again and again on every tick of a timer? Or is this not what you are really doing? If not, I think it would be much better if you explained exactly what you are doing in detail and show the complete relevant code.