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
|
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.
|
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!
|
Rank: Member Groups: Member
Joined: 6/25/2022 Posts: 10
|
Great! Thanks a lot it works :-)
|
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.
|
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); }
|
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
|
Rank: Member Groups: Member
Joined: 6/25/2022 Posts: 10
|
Great support, thanks. I just licensed EO...
|
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.
|