Page view counter

Silverlight Tips of the Day - Blog by Mike Snow

Game Programming with Silverlight

Silverlight Tip of the Day #14 – How to Right Click on a Silverlight Application.

You may have noticed that right clicking on a Silverlight application brings up the following context menu and configuration dialog:

Context Menu:

image

Configuration Dialog:

image

So what if you want to use right click in your application? While right click functionality is not currently supported in Silverlight, there is a work-around. I will step you through how to intercept the right click event, process it and display your own content instead of the Silverlight dialog.

Step 1. To start, let’s add a <TextBlock> control to our Page.xaml to track the status of the right click:

<UserControl x:Class="SilverlightApplication15.Page"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
    Width="400" Height="300">
    <Grid x:Name="LayoutRoot" Background="red">
        <TextBlock x:Name="MyField">Right click please.</TextBlock>
    </Grid>
</UserControl>

Step 2. Next, we need to set the Silverlight control to be windowless. Open the web page (i.e. default.aspx) that contains the Silverlight control and add the tag Windowless=”true” to it. Example:

<asp:Silverlight ID="Xaml1" runat="server" Windowless="true" Source="~/ClientBin/SilverlightApplication15.xap" MinimumVersion="2.0.30523" Width="100%" Height="100%" />

Step 3: Finally, let’s take a look at the code we add to Page.xaml.cs.

  • I start by creating a new class called ContextMenuInterceptor. In this class constructor we attach an event “OnContextMenu” to the document for the HtmlPage. In order to use the HTMLPage object you will need to add a using statement referencing System.Window.Browser.
  • I then call e.PeventDefault(). This cancels further propagation of the right click event so that Silverlight does not receive it.
  • At this point, we have intercepted the right click and can do whatever else we want. In my case, I simply display the coordinates of where you right clicked.

Page.xaml.cs:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Windows.Shapes;
using System.Windows.Browser;
 
namespace SilverlightApplication15
{
    public partial class Page : UserControl
    {
        ContextMenuInterceptor _cmi = null;
        public Page()
        {
            InitializeComponent();
            _cmi = new ContextMenuInterceptor(MyField);           
        }
    }       
 
    public class ContextMenuInterceptor
    {
        TextBlock TextField;
 
        public ContextMenuInterceptor(TextBlock textField)
        {
            TextField = textField;
            HtmlPage.Document.AttachEvent("oncontextmenu", this.OnContextMenu);
        }
 
        private void OnContextMenu(object sender, HtmlEventArgs e)
        {
            TextField.Text = "Right Clicked Blocked at "+e.OffsetX+","+e.OffsetY;           
            e.PreventDefault();           
        }
    }
}

Thank you,
--Mike Snow

 Subscribe in a reader

Comments

Visual Web Developer Team Blog said:

Interested in learning something new about Silverlight almost every day? I will be posting “Tips of the

# July 1, 2008 1:54 PM

Microsoft Weblogs said:

You may have noticed that right clicking on a Silverlight application brings up the following context

# July 1, 2008 1:56 PM

MartyNY said:

you may want to go here and snag this guy's code he was way ahead of you and it works better. even lets you choose to display a HTML or XAML menu.  but he never updated for beta 2

http://www.rtlogicsystems.com

his would work even if the page was scrolled or the SL control was deeply nested.  you could probably even use that HTMLPage object to do what he did in javascript to say where in the SL control the click occured instead of where on the page.

marty

# July 1, 2008 2:38 PM

mike.snow said:

Marty- Thanks for the link. Looks like his method is to handle the right click from JScript. I am not sure how it is better (lot more code involved) but it's definitely a good alternative approach.

Btw, there is a lot more you can do to my code. It's only meant to be a starting place to get people going.

# July 1, 2008 3:17 PM

MartyNY said:

yup it is in the javascript.  if you want an HTML menu you handle it there if you want a XAML menu you call the managed code function from javascript with the coordinates it gives you that tells you the x and y of the click according to the SL control and not the page.

you guys should put your solutions together.  that would make the right click as easy to use as the other mouse events. it would be even better if microsoft just let us do what we wanted with the right click.

marty

# July 1, 2008 7:00 PM

nasa said:

在flash中 其提供了一个可定制话的右键菜单系统.(ContextMenu)

# July 2, 2008 12:10 AM

Community Blogs said:

16 posts today... yikes: Corrina Barber on Sparkling Client, Training CD update via Tim Heuer, Progressive

# July 2, 2008 2:29 AM

thomasvsundert said:

Why don't we get the configuration dialog when we right click a Silverlight app in Firefox?

# July 2, 2008 3:41 AM

Silverlight news for July 2, 2008 said:

Pingback from  Silverlight news for July 2, 2008

# July 2, 2008 3:53 AM

14 Silverlight Tips | DavideZordan.net said:

Pingback from  14 Silverlight Tips | DavideZordan.net

# July 2, 2008 4:31 AM

Alan Cobb said:

Since the Mac only has one mouse button, what happens there?  Is it Ctrl+Click or something?

# July 2, 2008 1:28 PM

mike.snow said:

Alan- This article talks about how to right click on the mac: www.ehow.com/how_6542_click-mac.html

# July 2, 2008 9:04 PM

Robert Folkesson said:

Jag tänkte jag skulle börja samla ihop bra länkar och resurser som jag hittar och publicera dessa veckovis

# July 4, 2008 9:47 AM

scommisso said:

Great post! Here's an extended version I put together that adds behavior similar to MouseEventArgs.

namespace SteveCommisso.Silverlight.Utils

{

 public class ContextMenuExtender

 {

   public UIElement ExtendedElement { get; private set; }

   public ContextMenuExtender(UIElement extendedElement) {

     this.ExtendedElement = extendedElement;

     HtmlPage.Document.AttachEvent("oncontextmenu", this.OnContextMenu);

   }

   public event RightClickHandler RightClick;

   private void OnContextMenu(object sender, HtmlEventArgs e) {

     if (RightClick != null) {

       if (ExtendedElement.IsHitTestVisible) {

         Point clickPoint = new Point(e.OffsetX, e.OffsetY);

         List<UIElement> hitElements = new List<UIElement>(ExtendedElement.HitTest(clickPoint));

         if (hitElements.Count > 0) {

           e.PreventDefault();

           e.StopPropagation();

           RightClick(this, new RightClickEventArgs(ExtendedElement, clickPoint));

         }

       }

     }

   }

 }

 public delegate void RightClickHandler(object sender, RightClickEventArgs e);

 public class RightClickEventArgs

 {

   public UIElement Source { get; private set; }

   public Point RelativePoint { get; private set; }

   public Point AbsolutePoint { get; private set; }

   internal RightClickEventArgs(UIElement source, Point absolutePoint) {

     this.Source = source;

     this.AbsolutePoint = absolutePoint;

     this.RelativePoint = GetPosition(Source);

   }

   public Point GetPosition(UIElement relativeTo) {

     GeneralTransform transform = Application.Current.RootVisual.TransformToVisual(relativeTo);

     return transform.Transform(AbsolutePoint);

   }

 }

}

# July 9, 2008 5:50 PM

scommisso said:

Oops -- posted too early. RightClickEventArgs should inherit from EventArgs:

public class RightClickEventArgs : EventArgs

Thanks for posting this... I had a really hacky javascript implementation I was working with. The key in this one was attaching the oncontextmenu event handler at the document level, rather than at an element level (for example, a DIV containing the Silverlight control). This allows it to work in FireFox/Safari as well as IE.

# July 9, 2008 6:00 PM

scommisso said:

Oops -- posted too early. RightClickEventArgs should inherit from EventArgs:

public class RightClickEventArgs : EventArgs

Thanks for posting this... I had a really hacky javascript implementation I was working with. The key in this one was attaching the oncontextmenu event handler at the document level, rather than at an element level (for example, a DIV containing the Silverlight control). This allows it to work in FireFox/Safari as well as IE.

# July 9, 2008 6:00 PM

Lyu- said:

Hi,

I'm just beginning with Silverlight...

Thanks a lot for this tip, it's very helpfull !

But there is something that I don't understand, it does work on IE7 but not on Firefox, I don't know how to fix it !

Scommisso said "The key in this one was attaching the oncontextmenu event handler at the document level, rather than at an element level (for example, a DIV containing the Silverlight control). This allows it to work in FireFox/Safari as well as IE." i don't know how to do it ?

Thanks in advance.

# July 21, 2008 6:49 AM

microsoft_kc said:

That's really Cool.

Thanks.

# August 7, 2008 6:48 AM

dbaechtel said:

The technique described doesn't seem to work in SL 2.0 B2.

Even though HtmlPage.Document.AttachEvent is being executed in the constructor of my Page UserControl, when I RightMouse click the OnContextMenu routine is not being called and the Silverlight Configuration popup stil appears. Why is that?

Also this design doesn't quite fill my need. I may have more than one UserControl that requires action on RightMouseButtonDown. I need to be able to add EventHandlers for each of the controls and not just the Browser page.

Any ideas on how to make this work?

# September 12, 2008 9:21 AM

mike.snow said:

Dbaechtel - What browser are you using?

Also, if you want to do it per user control just get the coordinates of where the right click occured then determine which control that click hit based upon its location on the screen. Just an idea.

# September 12, 2008 10:05 AM

mike.snow said:

Also, make sure to set windowless=true

# September 12, 2008 2:44 PM

haughtycool said:

If you set windowless=true, the Safari does not show the SL.

How can we solve this problem

# October 22, 2008 10:32 PM

Leochen said:

同flash一样,silverlight默认的右键菜单显示的内容也是关于这个插件的信息,要自定义silverlight右键菜单,其实也是很简单的。

首先需要自定义右键菜单的内容(当然你也可以根据需要...

# November 24, 2008 4:31 AM

Leochen said:

同flash一样,silverlight默认的右键菜单显示的内容也是关于这个插件的信息,要自定义silverlight右键菜单,其实也是很简单的。

首先需要自定义右键菜单的内容(当然你也可以根据需要...

# December 18, 2008 2:13 AM

Silverlight Tips of the Day - Blog by Mike Snow said:

The purpose of this post is to create an outline summary all the blogs from my Silverlight tips of the

# January 2, 2009 5:57 PM

Silverlight Tips of the Day - Blog by Mike Snow said:

The purpose of this post is to create an outline summary all the blogs from my Silverlight tips of the

# January 2, 2009 5:57 PM

o UAU nosso de cada dia said:

essa lista eu copiei desse blog bárbaro (acompanhe por RSS você também): uma lista de dicas super úteis

# January 3, 2009 6:25 AM

Axelino said:

Thanks!!! Before I read this post, I tried the javascript solution with something like "silverlightControl.Content.ActualSilverlightControl.ProcessMouseEvent(e);" which is an ugly hack and doesn't seem to work with Silverlight 3.

But this solution works really great! You are my hero :-)

# May 28, 2009 5:15 PM

Axelino said:

Also thanks to scommisso. I began to write the same class he did :-)

# May 28, 2009 5:22 PM

7 tips for extending browser functionality to Silverlight apps | Igor Ostrovsky Blogging said:

Pingback from  7 tips for extending browser functionality to Silverlight apps | Igor Ostrovsky Blogging

# June 4, 2009 3:50 AM

Montago said:

I can't make this sample work :(

# June 7, 2009 12:25 PM