I was recently looking at various ways of launching an external window from inside a Silverlight 2 application. Dusting off your javascript brain cell, you’ll recall that to open a popup dialog in “the old days”, we’d use window.open(). I knew about the HtmlBridge available in Silverlight 2 and I had used it for several other nifty interactions between my managed code and the DOM. So, I went looking for an equivalent to window.open() and came across the HtmlPage.PopupWindow() method. If you’ll recall the javascript window.open() method is defined as such:
window.open( [sURL] [, sName] [, sFeatures]);
The HtmlPage.PopupWindow() is defined as:
<blockquote> <p>HtmlPage.PopupWindow(string navigateToUri, string target, HtmlPopupWindowOptions options); </p> </blockquote> <p>Perfect! ...or so I thought. I fully expected that if I called <a href="http://msdn.microsoft.com/en-us/library/system.windows.browser.htmlpage.popupwindow(VS.95).aspx" target="_blank">PopupWindow</a>() like this:</p> <blockquote> <p>HtmlPopupWindowOptions options = new HtmlPopupWindowOptions() <br> { <br> Directories = false, <br> Location = false, <br> Menubar = false, <br> Status = false, <br> Toolbar = false, <br> }; <br>HtmlPage.PopupWindow(new Uri("<a href="https://training.atmosera.com">https://training.atmosera.com")</a>, "_blank", options);</p> </blockquote> <p>..that I'd get a new browser window with the default width/height on the monitor that the launching browser is on. </p> <p>After all, if I called <a href="http://msdn.microsoft.com/en-us/library/ms536651(VS.85).aspx" target="_blank">window.open()</a> with equivalent arguments as follows that's what would happen:</p> <blockquote> <p>string features = String.Format("directories=no,location=no,menubar=no,status=no,toolbar=no"); <br>HtmlPage.Window.Navigate(new Uri("<a href="http://www.r2musings.com">http://www.r2musings.com")</a>
, “_blank”, features);
Instead, I get a small window that launches on Monitor 1. I do my main work on my Monitor 2 and I kept waiting for my popup window only to realize that it was on the other monitor. I really hate applications that do this!
Looking into Reflector, the issue seems to be that if options is passed as null in the last parameter of PopupWindow(), the call is simply forwarded to window.open(). But, if you pass an instance of HtmlPopupWindowOptions (even with no properties set) to PopupWindow(), the ToFeaturesString() that gets called to convert this strongly-typed version of the features to the string that is needed for window.open() is also changing the height/width/top/left of the popup window.
Looking over the documentation…yes, I’m male and sometimes do that *after* nothing else works. ….anyway, there it is in the remarks of HtmlPage.PopupWindow(). All the ugly details and the admission that my popup would be altered. Documented or not, it’s not acceptable to my client and I’m not putting my name on anything that launches a browser on the wrong monitor!
That’s when I decided to have another look at HtmlWindow.Navigate() which seems to more accurately mirror the behavior that I would expect out of something that purports to wrap window.open(). Going this route, we lose the strong typing of the HtmlPopupWindowOptions, but in exchange we get exactly what we are expecting when calling window.open(). The call using HtmlWindow.Navigate() looks like this:
string features = “directories=no,location=no,menubar=no,status=no,toolbar=no”;
HtmlPage.Window.Navigate(new Uri(“http://www.r2musings.com”), “_blank”, features);
This will fire a new window on the correct monitor and will honor the default settings for width/height/top/left.
Here’s the code.
Here’s a live sample.