Custom Context Menu in Silverlight 3


Introduction

We are known to the fact that we can't have our customized context menu in Silverlight 3, but we can have our own built in i.e. customized context menu. Previously we have experienced how to disable the Right Click in Silverlight 3. In this article we will see how we can create our own context menu.

Creating Silverlight Project

Fire up Visual Studio 2008 and create a new Silverlight 3 Project. Name it as RightClick.

image1.gif

We will follow our traditional approach for disabling the default context menu of Silverlight 3.

image2.gif

Open RightClickTestPage.aspx and add the following line of code into the

"<div id="silverlightControlHost">"
<param name="windowless" value="True" />

Now add the following line of code inside the constructor after the InitializeComponent() method.

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

And add the method for OnRightClick as below:

private void OnRightClick(object sender, HtmlEventArgs e)
{
     e.PreventDefault();
}

Now if you will run your application you will see that your default context menu for Silverlight 3 is disabled.

Now the important part is design your own context menu. In this case I prefer you to use Blend 3 to design your own.

Open your solution in Blend 3.

Here in Blend 3 I am designing a Button to look alike menu.

image3.gif

I have added 7 buttons to my context menu.

Xaml code:

<StackPanel x:Name="myStackMenu" HorizontalAlignment="Left" VerticalAlignment="Top" Width="150">
<
StackPanel.Effect>
    <DropShadowEffect/>
</
StackPanel.Effect>
<
Button x:Name="option1" Style="{StaticResource MenuStyleButton}" Content="Red BackGround"/>
<
Button x:Name="option2" Style="{StaticResource MenuStyleButton}" Content="Green Background"/>
<
Button x:Name="option3" Style="{StaticResource MenuStyleButton}" Content="Blue BackGround"/>
<
Button x:Name="option4" Style="{StaticResource MenuStyleButton}" Content="Yellow BackGround"/>
<
Button x:Name="option5" Style="{StaticResource MenuStyleButton}" Content="Orange BackGround"/>
<
Button x:Name="option6" Style="{StaticResource MenuStyleButton}" Content="Pink BackGround"/>
<
Button x:Name="option7" Style="{StaticResource MenuStyleButton}" Content="Reset BackGround"/>
</
StackPanel>


The Style for the Menu Button is defined in App.xaml as follows:

<Style x:Key="MenuStyleButton" TargetType="Button">
                                <Setter Property="Background" Value="#FF1F3B53"/>
                                <Setter Property="Foreground" Value="#FF000000"/>
                                <Setter Property="Padding" Value="3"/>
                                <Setter Property="BorderThickness" Value="1"/>
                                <Setter Property="BorderBrush">
                                                <Setter.Value>
                                                               <LinearGradientBrush EndPoint="0.5,1" StartPoint="0.5,0">
                                                                                <GradientStop Color="#FFA3AEB9" Offset="0"/>
                                                                                <GradientStop Color="#FF8399A9" Offset="0.375"/>
                                                                                <GradientStop Color="#FF718597" Offset="0.375"/>
                                                                                <GradientStop Color="#FF617584" Offset="1"/>
                                                                </LinearGradientBrush>
                                                </Setter.Value>
                                </Setter>
                                <Setter Property="Template">
                                                <Setter.Value>
                                                                <ControlTemplate TargetType="Button">
                                                                                <Grid x:Name="grid" Background="White">
                                                                                                <VisualStateManager.VisualStateGroups>
                                                                                                                <VisualStateGroup x:Name="CommonStates">
                                                                                                                                <VisualState x:Name="Normal">
                                                                                                                                                <Storyboard>
                                                                                                                                                                <ColorAnimationUsingKeyFrames BeginTime="00:00:00" Duration="00:00:00.0010000" Storyboard.TargetName="grid" Storyboard.TargetProperty="(Panel.Background).(SolidColorBrush.Color)">
                                                                                                                                                                                <EasingColorKeyFrame KeyTime="00:00:00" Value="White"/>
                                                                                                                                                                </ColorAnimationUsingKeyFrames>
                                                                                                                                                </Storyboard>
                                                                                                                                </VisualState>
                                                                                                                                <VisualState x:Name="MouseOver">
                                                                                                                                                <Storyboard>
                                                                                                                                                                <ColorAnimationUsingKeyFrames BeginTime="00:00:00" Duration="00:00:00.0010000" Storyboard.TargetName="grid" Storyboard.TargetProperty="(Panel.Background).(SolidColorBrush.Color)">
                                                                                                                                                                                <EasingColorKeyFrame KeyTime="00:00:00" Value="#FF6987BF"/>
                                                                                                                                                                </ColorAnimationUsingKeyFrames>
                                                                                                                                                </Storyboard>
                                                                                                                                </VisualState>
                                                                                                                                <VisualState x:Name="Pressed"/>
                                                                                                                               
<VisualState x:Name="Disabled"/>
                                                                                                                </VisualStateGroup>
                                                                                                                <VisualStateGroup x:Name="FocusStates">
                                                                                                                                <VisualState x:Name="Focused"/>
                                                                                                                                <VisualState x:Name="Unfocused"/>
                                                                                                                </VisualStateGroup>
                                                                                                </VisualStateManager.VisualStateGroups>
                                                                                                <ContentPresenter x:Name="contentPresenter" VerticalAlignment="{TemplateBinding VerticalContentAlignment}" Content=
{
TemplateBinding Content}" ContentTemplate="{TemplateBinding ContentTemplate}" Margin="10,5,5,5"/>
                                                                                </Grid>
                                                                </ControlTemplate>
                                                </Setter.Value>
                                </Setter>
                </Style>


Always remember to make the visibility of the Stack Panel to Collapse. Now make the visibility of the Stack Panel Visible in OnRightClick() method. You can have the position of the context menu by taking the e.ClientX and e.ClientY as follows:

private void OnRightClick(object sender, HtmlEventArgs e)|
        {
            e.PreventDefault();
            myStackMenu.Visibility = Visibility.Visible;
            myStackMenu.Margin = new Thickness(e.ClientX,e.ClientY,0,0);
        }

If you run the application now you will find the below menu (without menu functioning).

image4.gif

We will add the below to event handlers to handle the visibility of the Menu.

private void myStackMenu_LostFocus(object sender, RoutedEventArgs e)
        {
            myStackMenu.Visibility = Visibility.Collapsed;
        }

        private void LayoutRoot_MouseLeftButtonDown(object sender, MouseButtonEventArgs e)
        {
            myStackMenu.Visibility = Visibility.Collapsed;
        }

Now for each Button Click we will change the ClickMode to Press. As shown below:

image5.gif

Write the below lines of code in the respective click events of the buttons (options).

private void option1_Click(object sender, RoutedEventArgs e)
        {
            LayoutRoot.Background = new SolidColorBrush(Colors.Red);
            myStackMenu.Visibility = Visibility.Collapsed;
        }

        private void option2_Click(object sender, RoutedEventArgs e)
        {
            LayoutRoot.Background = new SolidColorBrush(Colors.Green);
            myStackMenu.Visibility = Visibility.Collapsed;
        }

        private void option3_Click(object sender, RoutedEventArgs e)
        {
            LayoutRoot.Background = new SolidColorBrush(Colors.Blue);
            myStackMenu.Visibility = Visibility.Collapsed;
        }

        private void option4_Click(object sender, RoutedEventArgs e)
        {
            LayoutRoot.Background = new SolidColorBrush(Colors.Yellow);
            myStackMenu.Visibility = Visibility.Collapsed;
        }

        private void option5_Click(object sender, RoutedEventArgs e)
        {
            LayoutRoot.Background = new SolidColorBrush(Colors.Orange);
            myStackMenu.Visibility = Visibility.Collapsed;
        }

        private void option6_Click(object sender, RoutedEventArgs e)
        {
            LayoutRoot.Background = new SolidColorBrush(Colors.Magenta);
            myStackMenu.Visibility = Visibility.Collapsed;
        }

        private void option7_Click(object sender, RoutedEventArgs e)
        {
            LayoutRoot.Background = new SolidColorBrush(Colors.White);
            myStackMenu.Visibility = Visibility.Collapsed;
        }


image6.gif

Now play with this menu more to invent more. And do let me know if you find any new idea.

Hope you enjoy this article.


Similar Articles