Page 1 of 2
Best way to implement bBrowser codeblocks in X#
Posted: Wed Jun 22, 2022 11:09 am
by ic2
In the large program we are converting we use (in the end) a codeblock as parameter of add a bDataColumn like this:
This then calls a
method of the class of the DBServer used in the call, e.g.
Code: Select all
METHOD BbrowserMethod(n) CLASS MyAddressDBServer
if n==8
return self:Fieldget(#Phone)
endif
Not exactly the used code but it illustrates how we use it.
In VO we can freely have these methods anywhere in the program. In X# this won't work as it needs to reside in the same program where we define the specific dbServer class. And that is only possible if we add a reference to bBrowser libraries in library with DBServers which doesn't feel correct.
I thought I could solve this by creating a
function like this:
Code: Select all
{||:bBrowserfunction(8,self:Server)}
Function bBrowserfunction(n,oServer)
// do something with the parameters and return a value
and wherever the current methods says something like self:Fieldget(#whatever) I could use oServer:Fieldget(#whatever) instead.
However, as soon as I put SELF in the parameter I get
No self available although self is used within test of the calling method without problems.
What is the best way to solve this without including bBrowser library references in a library with dbservers?
Dick & Frank
Best way to implement bBrowser codeblocks in X#
Posted: Wed Jun 22, 2022 7:05 pm
by wriedmann
Hi Dick,
I don't know if the compiler option "all methods are virtual" changes something here.
Wolfgang
Best way to implement bBrowser codeblocks in X#
Posted: Wed Jun 22, 2022 8:06 pm
by ic2
Hello Wolfgang,
I am not sure what would change. According to Chris, in an earlier answer:
By default METHODs in .Net are not VIRTUAL, meaning that you cannot override a method of a base class by redefining it in a child class, like we do in VO, this instead creates a completely new method, from the CLR's point of view. In order to make a (base) method overrideable, you must explicitly mark it with the VIRTUAL keyword. Or, you can simply enable the "All instance methods virtual" project option, which tells the compiler to make all methods VIRTUAL by default, for compatibility with VO.
What I understand from this is that I can e.g. write a virtual method Skip() in a dbserver class doing something different than the default dbServer skip.
But I would say it does not mean that we can move these methods of the several dbserver classes, called by the codeblock, back to a more logical library with bBrowser included? I thought it was not possible in X# to create methods of a class in a library where the class isn't defined. regardless this setting?
Dick
Best way to implement bBrowser codeblocks in X#
Posted: Wed Jun 22, 2022 10:52 pm
by Chris
Hi Dick,
I do not understand why you would need to add references to the bbRowser libraries in the DBServer libraries. Maybe you can explain more in depth the structure of your app and the problem itself?
.
Best way to implement bBrowser codeblocks in X#
Posted: Thu Jun 23, 2022 8:18 am
by wriedmann
Hi Dick,
when you are using virtual methods, the bBrowser calls the correct method defined in your application, not a method that is defined in the standard DBServer class because it uses late binding.
Even in Core X# (and even C#) it is possible to call methods that are defined in the main executable from a library.
For me that is working.
Maybe I have to make a sample for you.
Wolfgang
Best way to implement bBrowser codeblocks in X#
Posted: Thu Jun 23, 2022 10:56 am
by FdeRaadt
Hi Wolfgang, Chris and more
Making the "all methods are virtual" does not change the end result.
We have a bBrowserfunction that essentially uses the FieldGet method of DBServer to return a logic.
Code: Select all
Class Contact_External_Class Inherit Contact
METHOD bBrowserFunction CLASS Contact_external_class
We've noticed the issue that our bBrowserfunction is never reached unless we place this method directly in the same project as where we define our DBServer Classes. I've tried making the Method virtual but nothing changes.
We would like to find a different approach due to the fact that most projects in our solution have a single responsibility. By moving this method to a Project that handles DBServer we're mixing responsibilities. This is something we're actively trying to avoid.
p.s Dont ask why me why our METHOD is called bBrowserfunction.
Frank
Best way to implement bBrowser codeblocks in X#
Posted: Thu Jun 23, 2022 1:54 pm
by ic2
I add to this, to answer Chris, one of the functions contains this code:
Code: Select all
CASE n == 3
IF Left(SELF:FIELDGET(#SomeField),1) == "1"
RETURN bCompoundValue{bIcon{OKKL{},16},,,BALIGN_RIGHT}
Because of bCompoundValue{, a bBrowser reference is required.
Also Frank posts
Contact_external_class. This I think should be
Contact (the name of one of the dbservers where this method should work on). It originally didn't work at all until I discovered that the class was changed to external_Class. We renamed it back to the original dbserver subclass contact, but that requires the method to be moved to the dbserver based library which, as Frank mentions, should not need bBrowser includes. But we can not move the codeblock called method to a more logical place without giving up the access to the dbServer which obviously is essential.
Dick
Best way to implement bBrowser codeblocks in X#
Posted: Thu Jun 23, 2022 3:02 pm
by Chris
Guys,
Is this about the app of yours of which I already have the code for? If yes, can you please point me exactly to the part of the code that has this issue, so I can look into it directly and understand the problem? If not, can you create a sample demonstrating the problem? Please note that we have 40C here all day, so if I don't see the problem myself or get a very clear description, it's very unlikely that I will understand what's going on
.
Best way to implement bBrowser codeblocks in X#
Posted: Thu Jun 23, 2022 4:50 pm
by robert
Frank
Have you considered making bBrowserFunction an extension method to the Contact class ?
The VOPad example in the X# help shows how to do that:
https://www.xsharp.eu/help/example-2-th ... ample.html
Robert
Best way to implement bBrowser codeblocks in X#
Posted: Thu Jun 23, 2022 5:36 pm
by wriedmann
Hi Dick,
ok, if I understand it correctly, you have defined the Contact:FieldGet() method in a different assembly than the one that contains the Contact class.
That will never work in X#, and I don't know if an extension method defined in the main library will be called by the bBrowser code. (@Robert: late binding uses extension methods?)
So, you could use the CreateInstance() function (or the relative Reflection method) and put your code into the library where the contact class is defined:
Code: Select all
IF Left(SELF:FIELDGET(#SomeField),1) == "1"
RETURN CreateInstance( #bCompoundValue, bIcon{OKKL{},16},,,BALIGN_RIGHT)
That should definitely work.
Or, maybe you can do some other thing: subclass the Contacts class, define the FieldGet() method in the subclass and use the subclass instead of the Contacts class.
Wolfgang