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