Monday, May 26, 2008

Quick Silverlight tip: How to open new window or tab by using HyperlinkButton and Ctrl-Shift modifiers

Regular behavior of any HTML anchor element is to open new Window if you’re clicking the link with Shift key and new Tab, if you’re clicking with Ctrl key or middle mouse button. Unfortunately, Silverlight HyperlinkButton does not support opening new window or tab. It also does not support key modifiers. What to do?

image
(rotary reading desk – first tabbed browser, invented in 1588. via Athanasius Kircher society)

First of all, request this feature. This is regular behavior and there is no reason not to support it in Silverlight. Next, we should do something to fix it by now. So let’s start.

We should understand what happens under the hoods of HyperlinkButton. It does not generate html anchor, however it uses window.navigate to move. One of HyperlinkButton properties is TargetName – this one is actually html ”target” attribute. So we can just change it according the keystrokes. This is acceptable, but ugly solution. The better one is to subclass HyperlinkButton and check KeyModifiers. Then void Click event and navigate

if(Keyboard.Modifiers == ModifierKeys.Control | Keyboard.Modifiers == ModifierKeys.Shift)
            {
                this.TargetName=”_blank”;
            }
            base.OnClick();

So far so good, but not good enough. What will happen if user explicitly set TargetName Value? We’ll override it and this is something we wont to do. Also, following approach will work differently between browsers. For example in IE it will open new window, while in FF – new tab by default. So how to avoid it?

We can use HtmlPage.Window.Navigate method to assure opening of new window. Navigate method receives three parameter, Uri for navigation address, target frame and “target features”. What are those target features? Actually, it parameters we’re using in JavaScript for window.open method. Thus HtmlPage.Window.Navigate(new Uri(“http://blogs.microsoft.co.il/blogs/tamir”,null,”menubar=1,resizable=1,width=350,height=250”) will open resizable window with menubar and size of 350x250.

Very well. Now we almost finished, but how to assure, that I opened new tab? Actually, we cannot until all browsers will support CSS3. In CSS3 we have style attributes, which can target into tab or window. By now, the only workaround is to use IWebBrowser2::Navigate2 method for IE and pass 0x1000 (navOpenInBackgroundTab) as second parameter. This “heck” can only be done in Full trust mode. For Mozilla (FireFox or any Geco + ancestors) we should use nsIBrowserWindow::OPEN_NEWTAB override for nsIBrowserWindow::OPEN_NEWWINDOW. There is no known way to do it for Safari.

So, the best thing can be done is inheritance of build-in feature of any supported browser to handle Ctrl/Shift modifiers for force opening links in other tabs or new windows.

Have a nice week and be good people.

No comments: