xsharp.eu • How to translate this Invoke/Delegate
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.