Welcome Guest Search | Active Topics | Sign In | Register

Howto Create HTML Event Proxy Options
pixafe
Posted: Saturday, June 25, 2022 7:41:29 AM
Rank: Member
Groups: Member

Joined: 6/25/2022
Posts: 10
Hi,

I am evaluating the eo.webbrowser for windows forms which looks good.
But I do not find a solution for connecting callback methods in c# when interacting with javascript / dom.
E.G. I need to do the following:

var image = GetHtmlElementFromDom(_document, "inlayImage");
if (image != null)
{
HtmlEventProxy.Create("onclick", image, LazyLoadImage);
}

where LazyLoadImage is the c# Method which should be called, when user klicks on the DOM Element "inlayImage" using the onclick function.

Thanks
Alex
eo_support
Posted: Saturday, June 25, 2022 12:22:56 PM
Rank: Administration
Groups: Administration

Joined: 5/27/2007
Posts: 24,217
Hi,

Please see here for more details:

https://www.essentialobjects.com/forum/postst12354_Migration-from-SystemWindowsFormsWebBrowser-to-EOWebbrowser-howto-attach-events.aspx

Note that you CAN NOT call back into the JavaScript engine directly inside your C# side event handler. If you need to execute additional JavaScript code inside your C# side event handler, please use Control.BeginInvoke to delay the code.

Thanks!
pixafe
Posted: Monday, June 27, 2022 4:35:12 AM
Rank: Member
Groups: Member

Joined: 6/25/2022
Posts: 10
Hi Support,
thanks for further information. I implemented the callbacks as follows:

1. After WebView is loaded, I connect the HTML-Element-Events with my class MapView
public MapView(..) {
_browser.WebView.LoadCompleted += ConnectEvents;
_browser.WebView.JSExtInvoke += WebViewJsExtensionInvoke;
}

private void ConnectEvents(object sender, LoadCompletedEventArgs e) {
_browser.WebView.EvalScript(
@"document.getElementById('inlayImage').onclick=function(){{eoapi.extInvoke('LazyLoadImage');}}");
...
}

2. When click on a HTML Element, the event is handled in my class MapView.WebViewJsExtensionInvoke:

private void WebViewJsExtensionInvoke(object sender, JSExtInvokeArgs e) {
switch (e.FunctionName)
{
case "LazyLoadImage":
LazyLoadImage(this, null);
break;
...

3. All Cross calls to JavaScript are delayed using Control.Invoke:

private void LazyLoadImage(object sender, EventArgs e) {
_lblMapItemCount.DelayCrossCall(delegate {
var image = SelectedImage();
if (image != null) {
_lblMapItemCount.DelayCrossCall(delegate
{
// Set <src> attribute for Image-HTML-Element
var s = new Uri(image.ImagePath).AbsoluteUri;
GetDocument?.InvokeFunction("setInlayImageSrc", s);
}); } }); }

Delay is implemented as Control Extension

internal static class ControlExtensions {
private static bool _needsJavascriptCrosscallDelay=true;

public static void DelayCrossCall(this Control control, Action code) {
if (_needsJavascriptCrosscallDelay) {
_needsJavascriptCrosscallDelay=false;
control.BeginInvoke(code);
return;
}

code.Invoke();
_needsJavascriptCrosscallDelay=true;
}


My Problem:
InvokeFunction of setInlayImageSrc throws an Exception:

Invoking function 'setInlayImageSrc' failed because the function to be called is invalid.

--> GetDocument?.InvokeFunction("setInlayImageSrc", s);

Stack:
bei EO.Base.Runtime.ylci(Object ltj, Exception ltk, Boolean ltl)
bei EO.WebBrowser.WebView.lmnc(Exception le, Boolean lf)
bei EO.WebBrowser.WebView.lmkq(vmiv gk, Action`1 gl, Boolean gm, Boolean gn, String go)
bei EO.WebBrowser.WebView.lmkq(vmiv gv, Action`1 gw, Boolean gx, String gy)
bei EO.WebBrowser.JSObject.lmkp(String wm, Boolean wn, Object[] wo)
bei EO.WebBrowser.JSObject.InvokeFunction(String functionName, Object[] args)
bei com.pixafe.pixafeCfg.settingpanel.admin.searches.radiussearch.map.MapView.<>c__DisplayClass29_0.<LazyLoadImage>b__1() in MapView.cs:Zeile 353.
bei com.pixafe.pixafeCfg.settingpanel.admin.searches.radiussearch.map.ControlExtensions.DelayCrossCall(Control control, Action code) in MapView.cs:Zeile 43.
bei com.pixafe.pixafeCfg.settingpanel.admin.searches.radiussearch.map.MapView.<LazyLoadImage>b__29_0() in MapView.cs:Zeile 348.
eo_support
Posted: Monday, June 27, 2022 6:59:16 AM
Rank: Administration
Groups: Administration

Joined: 5/27/2007
Posts: 24,217
Hi,

Your function setInlayImageSrc would be a method on the window object, not on the document object. Your code is trying to call it on the document object. As a result, it can not find the function.

Thanks!
pixafe
Posted: Monday, June 27, 2022 8:48:26 AM
Rank: Member
Groups: Member

Joined: 6/25/2022
Posts: 10
Great! Thanks a lot it works :-)
pixafe
Posted: Monday, June 27, 2022 9:00:03 AM
Rank: Member
Groups: Member

Joined: 6/25/2022
Posts: 10
But in some cases i get an exception with long stack trace:

Invoking function 'getElementById' failed because it is not safe to run JavaScript code at this moment.
This can occur if you are inside event handlers of certain WebView events such as JSExtInvoke.
In that case please consider delaying EvalScript calls until after the event handler returns.
bei System.Environment.GetStackTrace(Exception e, Boolean needFileInfo)
bei System.Environment.get_StackTrace()
bei EO.Base.BaseException..ctor(String ltb, Exception ltc)
bei EO.WebBrowser.WebView.lmkr(String gp, JSInvokeResult gq, vmiy gr, Exception& gs)
bei EO.WebBrowser.WebView.lmkq(vmiv gk, Action`1 gl, Boolean gm, Boolean gn, String go)
bei EO.WebBrowser.WebView.lmkq(vmiv gv, Action`1 gw, Boolean gx, String gy)
bei EO.WebBrowser.JSObject.lmkp(String wm, Boolean wn, Object[] wo)
bei EO.WebBrowser.DOM.Document.getElementById(String id)
bei com.pixafe.pixafeCfg.settingpanel.admin.searches.radiussearch.map.MapView.GetHtmlElementFromDom(Document document, String elementId) in C:\Entwicklung\pixafe9.6\pixafe Version 9.6\Cockpit\pixafeSettings\settingpanel\admin\searches\radiussearch\map\MapView.cs:Zeile 346.
bei com.pixafe.pixafeCfg.settingpanel.admin.searches.radiussearch.map.MapView.<>c__DisplayClass30_0.<GetHtmlElementFromDom>b__0() in C:\Entwicklung\pixafe9.6\pixafe Version 9.6\Cockpit\pixafeSettings\settingpanel\admin\searches\radiussearch\map\MapView.cs:Zeile 340.
bei System.RuntimeMethodHandle._InvokeMethodFast(Object target, Object[] arguments, SignatureStruct& sig, MethodAttributes methodAttributes, RuntimeTypeHandle typeOwner)
bei System.RuntimeMethodHandle.InvokeMethodFast(Object target, Object[] arguments, Signature sig, MethodAttributes methodAttributes, RuntimeTypeHandle typeOwner)
bei System.Reflection.RuntimeMethodInfo.Invoke(Object obj, BindingFlags invokeAttr, Binder binder, Object[] parameters, CultureInfo culture, Boolean skipVisibilityChecks)
bei System.Delegate.DynamicInvokeImpl(Object[] args)
bei System.Windows.Forms.Control.InvokeMarshaledCallbackDo(ThreadMethodEntry tme)
bei System.Windows.Forms.Control.InvokeMarshaledCallbackHelper(Object obj)
bei System.Windows.Forms.Control.InvokeMarshaledCallback(ThreadMethodEntry tme)
bei System.Windows.Forms.Control.InvokeMarshaledCallbacks()
bei System.Windows.Forms.Control.MarshaledInvoke(Control caller, Delegate method, Object[] args, Boolean synchronous)
bei System.Windows.Forms.Control.Invoke(Delegate method, Object[] args)
bei System.Windows.Forms.Control.Invoke(Delegate method)
bei com.pixafe.pixafeCfg.settingpanel.admin.searches.radiussearch.map.MapView.GetHtmlElementFromDom(Document document, String elementId) in C:\Entwicklung\pixafe9.6\pixafe Version 9.6\Cockpit\pixafeSettings\settingpanel\admin\searches\radiussearch\map\MapView.cs:Zeile 339.
bei com.pixafe.pixafeCfg.settingpanel.admin.searches.radiussearch.map.MapView.SelectedImage() in C:\Entwicklung\pixafe9.6\pixafe Version 9.6\Cockpit\pixafeSettings\settingpanel\admin\searches\radiussearch\map\MapView.cs:Zeile 416.
bei com.pixafe.pixafeCfg.settingpanel.admin.searches.radiussearch.map.MapView.<SelectedImage>b__35_0() in C:\Entwicklung\pixafe9.6\pixafe Version 9.6\Cockpit\pixafeSettings\settingpanel\admin\searches\radiussearch\map\MapView.cs:Zeile 409.
bei System.RuntimeMethodHandle._InvokeMethodFast(Object target, Object[] arguments, SignatureStruct& sig, MethodAttributes methodAttributes, RuntimeTypeHandle typeOwner)
bei System.RuntimeMethodHandle.InvokeMethodFast(Object target, Object[] arguments, Signature sig, MethodAttributes methodAttributes, RuntimeTypeHandle typeOwner)
bei System.Reflection.RuntimeMethodInfo.Invoke(Object obj, BindingFlags invokeAttr, Binder binder, Object[] parameters, CultureInfo culture, Boolean skipVisibilityChecks)
bei System.Delegate.DynamicInvokeImpl(Object[] args)
bei System.Windows.Forms.Control.InvokeMarshaledCallbackDo(ThreadMethodEntry tme)
bei System.Windows.Forms.Control.InvokeMarshaledCallbackHelper(Object obj)
bei System.Windows.Forms.Control.InvokeMarshaledCallback(ThreadMethodEntry tme)
bei System.Windows.Forms.Control.InvokeMarshaledCallbacks()
bei System.Windows.Forms.Control.MarshaledInvoke(Control caller, Delegate method, Object[] args, Boolean synchronous)
bei System.Windows.Forms.Control.Invoke(Delegate method, Object[] args)
bei System.Windows.Forms.Control.Invoke(Delegate method)
bei com.pixafe.pixafeCfg.settingpanel.admin.searches.radiussearch.map.MapView.SelectedImage() in C:\Entwicklung\pixafe9.6\pixafe Version 9.6\Cockpit\pixafeSettings\settingpanel\admin\searches\radiussearch\map\MapView.cs:Zeile 408.
bei com.pixafe.pixafeCfg.settingpanel.admin.searches.radiussearch.map.MapView.<LazyLoadImage>b__31_0() in C:\Entwicklung\pixafe9.6\pixafe Version 9.6\Cockpit\pixafeSettings\settingpanel\admin\searches\radiussearch\map\MapView.cs:Zeile 356.
bei com.pixafe.pixafeCfg.settingpanel.admin.searches.radiussearch.map.ControlExtensions.DelayCrossCall(Control control, Action code) in C:\Entwicklung\pixafe9.6\pixafe Version 9.6\Cockpit\pixafeSettings\settingpanel\admin\searches\radiussearch\map\MapView.cs:Zeile 43.
bei com.pixafe.pixafeCfg.settingpanel.admin.searches.radiussearch.map.MapView.LazyLoadImage(Object sender, EventArgs e) in C:\Entwicklung\pixafe9.6\pixafe Version 9.6\Cockpit\pixafeSettings\settingpanel\admin\searches\radiussearch\map\MapView.cs:Zeile 354.
bei com.pixafe.pixafeCfg.settingpanel.admin.searches.radiussearch.map.MapView.WebViewJsExtensionInvoke(Object sender, JSExtInvokeArgs e) in C:\Entwicklung\pixafe9.6\pixafe Version 9.6\Cockpit\pixafeSettings\settingpanel\admin\searches\radiussearch\map\MapView.cs:Zeile 190.
bei EO.WebBrowser.WebView.lmmd(hjiq ji, vmiy jj)
bei EO.WebBrowser.WebView.lmne(hjiq li, vmiy lj)
bei EO.WebBrowser.WebView.lmnd(hjiq lg, vmiy lh)
bei EO.WebBrowser.WebView.lmli(hjiq hz, vmiy ia)
bei EO.Internal.hjiq.oxcn(mhum e, IntPtr f, Int32 g, IntPtr h, IntPtr i, Boolean& j)
bei EO.Internal.mhum.scih(IntPtr rrw, Int32 rrx, IntPtr rry, IntPtr rrz, Boolean& rsa)
bei EO.Internal.mhum.dtqa(IntPtr odx, Int32 ody, IntPtr odz, IntPtr oea, Boolean& oeb)
bei EO.Internal.mhum.dtpz(IntPtr odt, Int32 odu, IntPtr odv, IntPtr odw)
bei System.Windows.Forms.UnsafeNativeMethods.DispatchMessageW(MSG& msg)
bei System.Windows.Forms.Application.ComponentManager.System.Windows.Forms.UnsafeNativeMethods.IMsoComponentManager.FPushMessageLoop(Int32 dwComponentID, Int32 reason, Int32 pvLoopData)
bei System.Windows.Forms.Application.ThreadContext.RunMessageLoopInner(Int32 reason, ApplicationContext context)
bei System.Windows.Forms.Application.ThreadContext.RunMessageLoop(Int32 reason, ApplicationContext context)
bei System.Windows.Forms.Application.Run(Form mainForm)
bei com.pixafe.pixafeCfg.Program.Main(String[] args) in Program.cs:Zeile 104.

pixafe
Posted: Monday, June 27, 2022 9:01:37 AM
Rank: Member
Groups: Member

Joined: 6/25/2022
Posts: 10
Even although this is implemented like this:

/// <summary>
/// Retruns IHTMLElement with element-id, if found
/// </summary>
private Element GetHtmlElementFromDom(Document document, string elementId)
{
if (_needsJavascriptCrosscallDelay)
{
_needsJavascriptCrosscallDelay = false;
return (Element)_lblMapItemCount.Invoke(
new Func<Element>(() => GetHtmlElementFromDom(document, elementId))
);
}

_needsJavascriptCrosscallDelay = true;
if (document == null || string.IsNullOrEmpty(elementId)) return null;
return document.getElementById(elementId);
}
eo_support
Posted: Monday, June 27, 2022 9:09:34 AM
Rank: Administration
Groups: Administration

Joined: 5/27/2007
Posts: 24,217
Hi,

You should ALWAYS use BeginInvoke to delay the call when you try to call Javascript code from your event handler. Your stack trace showed that you are calling Invoke, not BeginInvoke.

Thanks
pixafe
Posted: Tuesday, June 28, 2022 9:48:08 AM
Rank: Member
Groups: Member

Joined: 6/25/2022
Posts: 10
Great support, thanks. I just licensed EO...
eo_support
Posted: Tuesday, June 28, 2022 12:57:23 PM
Rank: Administration
Groups: Administration

Joined: 5/27/2007
Posts: 24,217
Great. Glad to hear that! Please feel free to let us know if you run into any other problem with the product.


You cannot post new topics in this forum.
You cannot reply to topics in this forum.
You cannot delete your posts in this forum.
You cannot edit your posts in this forum.
You cannot create polls in this forum.
You cannot vote in polls in this forum.