i am trying to create a simple WPF tabbed WebControl view using Awesomium 1.7.4.2. The idea is that I have a main ClosableTab
(which extends TabItem
) that contains a WebControl (let's say it HomeTab
) which in turn loads a certain url. From HomeTab
the user can open other tabs, ie each new web page opens at a new tab item wich contains a WebControl
. Each WebControl has these handlers:
webTabControl.CertificateError += webControl_CertificateError;
webTabControl.NativeViewInitialized += webControl_NativeViewInitialized;
webTabControl.ShowContextMenu += webControl_ShowContextMenu;
webTabControl.LoadingFrameComplete += webControl_LoadingFrameComplete;
webTabControl.LoadingFrameFailed += webControl_LoadingFrameFailed;
On
webControl_NativeViewInitialized
I create a global javascript object calledDotApi
and then bind some javascript methods on it such asopenTab
.There is a method called
JSHandler
that handles the results ofDotApi
methods.When
DotApi.openTab
is called fromHomeTab
, a new tab is created, added inwebTabControl
(tab_control
) and and then shown (if user clicked with left click).On
tabItem_loaded
a newwebControl
is created that binds the abovewebControl
handlers and is added as content onTabItem
.If user clicked with middle click,
webControl.ApplyTemplate()
is called (since middle clicks, open the new tabs in the background, ie the newTabItem
doesn't get focused).
It seems quite straight-forward. This works fine almost every time. The problem is that one time in hundred it comes with this error:
The specified name (DotApi), is reserved. It either represents an HTML DOM object, or an object variable already available in the page. Use ExecuteJavascriptWithResult after DocumentReady, to obtain this object.
Parameter name: name
I noticed that the above error occurs only when the error below shows up:
A first chance exception of type 'System.ArgumentException' occurred in Awesomium.Windows.Controls.dll
I looked at debug.log and noticed that this error is similar to my error with the only difference on the specified name:
The specified name (external), is reserved. It either represents an HTML DOM object, or an object variable already available in the page. Use ExecuteJavascriptWithResult after DocumentReady, to obtain this object.
Parameter name: name
My questions are:
- Why this error occurs so rarely?
- How can it be fixed?
Below is sample code to help you understand the flow:
webControl_NativeViewInitialized
private void webControl_NativeViewInitialized(object sender, WebViewEventArgs e)
{
WebControl wbControl = sender as WebControl;
try
{
JSObject jsobject = wbControl.CreateGlobalJavascriptObject("DotApi");
// openTab will be invoked each time a new page opens in new tab
jsobject.Bind("openTab", false, JSHandler);
}
catch (Exception ex)
{
Debug.WriteLine("NativeViewInitialized exception: " + ex.Message);
}
}
JSHandler
private void JSHandler(object sender, JavascriptMethodEventArgs args)
{
try
{
if (!args.MustReturnValue)
{
case @"openTab": // parameters: url, type(order,index,map), true/fasle(focus on new tab),arguments
if (args.Arguments.Length > 0)
{
Application.Current.Dispatcher.BeginInvoke(
new OpenNewTabDelegate(OpenNewTab), args.Arguments);
}
break;
}
}
catch (Exception e)
{
MessageBox.Show("JSHandler Exception: " + e.Message);
}
}
OpenNewTab
private void OpenNewTab(JSValue[] arguments)
{
try
{
ClosableTab theTabItem = new ClosableTab(this);
theTabItem.Title = "Loading";
theTabItem.Loaded += (s_, e_) => theTabItem_Loaded(theTabItem, e_, arguments);
tab_control.Items.Add(theTabItem);
if (!(bool)arguments[2]) // whether it focus on new window or not
{
theTabItem.Focus();
}
}
catch (Exception e)
{
Debug.WriteLine("OpenNewTab exception e: " + e.Message);
}
}
theTabItem_Loaded
private void theTabItem_Loaded(object sender, RoutedEventArgs e, JSValue[] arguments)
{
ClosableTab currentTab = sender as ClosableTab;
currentTab.Loaded -= (s_, e_) => theTabItem_Loaded(currentTab, e_, arguments);
WebControl webTabControl = new WebControl();
webTabControl.Source = new Uri((string)arguments[0]);
webTabControl.CertificateError += webControl_CertificateError;
webTabControl.NativeViewInitialized += webControl_NativeViewInitialized;
webTabControl.ShowContextMenu += webControl_ShowContextMenu;
webTabControl.LoadingFrameComplete += webControl_LoadingFrameComplete;
webTabControl.LoadingFrameFailed += webControl_LoadingFrameFailed;
currentTab.Content = webTabControl;
webTabControl.Dispatcher.BeginInvoke(new Action(() =>
{
// Load the webcontrol in the backgound
if(!currentTab.IsSelected){
webTabControl.ApplyTemplate();
}
}));
}
After debugging i figured out that it was a timedOut exception from awesomium. To handle it, each time i create a webControl i set its property:
SynchronousMessageTimeout = 0
. If you don't set it to 0 the default value will be 800ms according to current documentation SynchronousMessageTimeoutThis prevented the below exceptions from appearing: