PlotElement is a visual presentation of data such as bar on the bar chart or slice of pie on the pie chart. This blog implementation provides a Context Menu option to customize the individual PlotElements in C1Chart for Silverlight. Lets quickly see the various steps to implement the Context Menu.

Remove the default Silverlight Context Menu

By default, when you right click on a Silverlight page, it displays a Silverlight menu. You need to cancel this menu by setting the e.handled property to true in MouseRightButtonDown event for Chart control.


void \_chart\_MouseRightButtonDown(object sender, MouseButtonEventArgs e)  
{  
   e.Handled = true;  
}  

Create Context Menu Items

Next step is to create the Context Menu. For this we'll use C1ContextMenu with two C1MenutItems 'BackGround' and 'Reset Background'. Clicking the 'Background' menu item will change the backcolor for the PlotElement to Gray shade and 'Reset Background' will change its background to default Series BackColor. Add the following code block in the page constructor for this :


C1.Silverlight.C1ContextMenu menu;  
menu = new C1.Silverlight.C1ContextMenu();  
C1MenuItem menuitem = new C1MenuItem();  
menuitem.Header = "BackGround";  
menuitem.Click += new EventHandler<SourcedEventArgs>(menuitem_Click);  
menu.Items.Add(menuitem);  

menuitem = new C1MenuItem();  
menuitem.Header = "Reset Background";  
menuitem.Visibility = System.Windows.Visibility.Collapsed;  
menuitem.Click +=new EventHandler<SourcedEventArgs>(menuitem_Click);  
menu.Items.Add(menuitem);  

Assign Mouse Event Handlers to PlotElements

Once the ContextMenu has been created, assign MouseRightButtonDown and MouseRightButtonUp events for the individual PlotElements. To assign event handlers, you need to access the individual PlotElements which can be done using PlotElementLoaded event.


foreach (DataSeries ds in _chart.Data.Children)  
    ds.PlotElementLoaded += new EventHandler(ds_PlotElementLoaded);  

void ds_PlotElementLoaded(object sender, EventArgs e)  
{  
     (sender as PlotElement).MouseRightButtonDown += new MouseButtonEventHandler(PlotElement_MouseRightButtonDown);  
     (sender as PlotElement).MouseRightButtonUp += new MouseButtonEventHandler(PlotElement_MouseRightButtonUp);  
}  

For MouseRightButtonUp event to fire for PlotElements, it is necessary to set e.handled property to true in MouseRightButtonDown event. It also stores the reference of the PlotElement on which right mouse button is clicked.


PlotElement currentPE;  
void PlotElement_MouseRightButtonDown(object sender, MouseButtonEventArgs e)  
{  
     currentPE = sender as PlotElement;  
     e.Handled = true;  
}  

Next we need to toggle the visibility of the Menu Items based on the backcolor of the current PlotElement. In case the PlotElement backcolor is set to default DataSeries color, show the MenuItem 'Background' and hide the menu option 'Reset Background'. Similarly you need to do the vice versa, when color has already been changed. To keep track of the changed backcolor for the PlotElements, Tag property for the PlotElement is used. This property, being an Object, holds the original color of the DataSeries. Following code in MouseRightButtonUp event shows the implementation.


void PlotElement_MouseRightButtonUp(object sender, MouseButtonEventArgs e)  
{  
    if (currentPE != (sender as PlotElement))  
      return;  

    if ((currentPE.Content as Path).Tag != null)  
    {  
       (menu.Items[0] as C1MenuItem).Visibility = System.Windows.Visibility.Collapsed;  
       (menu.Items[1] as C1MenuItem).Visibility = System.Windows.Visibility.Visible;  
    }  
    else  
    {  
       (menu.Items[0] as C1MenuItem).Visibility = System.Windows.Visibility.Visible;  
       (menu.Items[1] as C1MenuItem).Visibility = System.Windows.Visibility.Collapsed;  
    }  

    menu.Show(currentPE,e.GetPosition(currentPE));  
}  

Define Click Action for Menu Items

Now lets quickly define the Click actions for Menu Items. In case 'Background' menu item is selected, change the backcolor of the PlotElement to 'Gray' shade and save the original backcolor in its Tag property. This will be used to reset the backcolor when Reset Background menu item is clicked.


void menuitem_Click(object sender, SourcedEventArgs e)  
{  
    C1MenuItem currMenu = sender as C1MenuItem;  

    if (currMenu.Header.ToString() == "BackGround")  
    {  
       if (currentPE != null)  
       {  
          (currentPE.Content as Path).Tag = (currentPE.Content as Path).Fill;  
          (currentPE.Content as Path).Fill = new SolidColorBrush(Colors.Gray);  
       }  
    }  
    else  
    {  
          (currentPE.Content as Path).Fill = (currentPE.Content as Path).Tag as SolidColorBrush;  
          (currentPE.Content as Path).Tag = null;  
    }  
}  

Putting up all the above code blocks together will implement the Context Menu on the PlotElements. Similarly you can add further menu items as per your requirement. Download the attached samples for complete implementation. Download Sample VB Download Sample C#