The Popup contains the UI elements that will make up our ad-hoc context ‘menu’. The purpose of the containing Canvas is to be able to detect mouse clicks outside of the menu in order to close the menu. (We’ll add event handlers to do that later.)Notice that we’re using a data binding expression to show the title of a talk. This XAML assumes that the popup’s data context will be set to refer to a Talk entity. We’ll do that when we show the menu.Further up the XAML file find the <ItemsControl.ItemTemplate> for the second ItemsControl. (If you did the optional part of the last exercise, you would have changed this to a <ListBox.ItemTemplate>, so find that instead.) Inside this there will be a <DataTemplate> containing a <Grid> element. This element contains all the content representing a single talk in the user’s chosen schedule. We’ll attach the right mouse button handlers to this, but first, we need to make sure that the whole of the Grid is clickable. By default, panels have no value in their Background properties, meaning that mouse input falls through to the element behind.
Set the Background of the Grid inside the ItemTemplate for the innermost ItemsControl to "Transparent".
Add Right Click Support
Add two event handlers to this Grid element, for the MouseRightButtonDown and MouseRightButtonUp events.
Context menus are normally opened on the right mouse button up event, but Silverlight won’t give us that event unless we marked the down event as handled, so we need both handlers.
In the code behind, find the MouseRightButtonDown handler you just added.
Set the MouseButtonEventArgs (‘e’) argument’s Handled property to true.
Implement the MouseRightButtonUp handler as follows:
Private Sub Grid_MouseRightButtonUp(ByVal sender As Object, ByVal e As MouseButtonEventArgs)
Dim mousePosition As Point = e.GetPosition(popupContainer)
Dim itemTemplateInstance As FrameworkElement = CType(sender, FrameworkElement)
menuPopup.DataContext = itemTemplateInstance.DataContext
menuPopup.IsOpen = True
Run the application.
Right-click on an item in the list on the right. You will see the popup appear:
Closing the Popup Menu
The popup doesn’t go away yet when you click elsewhere. We need to handle clicks outside of the popup. For that, we need to make sure that the containing canvas is able to receive mouse clicks.
Add the following code at the end of the MouseRightButtonUp handler:
popupContainer.Background = new SolidColorBrush(Colors.Transparent);
popupContainer.Background = new SolidColorBrush(Colors.Transparent)
Back in the XAML, go to the popupContainer Canvas.
Add a single event handler function for left and right mouse button down events, and make it do the following:
Run the application again. You should now be able to dismiss the menu by clicking outside of it within the Silverlight application.
We need to wire our button into some behavior. For this, we’ll need an extra method on the server.
Add Support for Removing a Session
In the EventManagerDomainService, add the following method:
public void RemoveTalkFromUserSchedule(int talkID)
Attendee attendee = GetOrCreateAttendeeForCurrentUser();
var astQuery = from entry in attendee.AttendeeScheduleTalks
where entry.TalkID == talkID
AttendeeScheduleTalk ast = astQuery.SingleOrDefault();
if (ast != null)
Public Sub RemoveTalkFromUserSchedule(ByVal talkID As Integer)
Dim attendee As Attendee = GetOrCreateAttendeeForCurrentUser()
Dim astQuery = From entry In attendee.AttendeeScheduleTalks
Where entry.TalkID = talkID
Dim ast As AttendeeScheduleTalk = astQuery.SingleOrDefault()
If ast IsNot Nothing Then
Open the SchedulePlannerViewModel class.
This time we won’t be adding a command because the menu XAML doesn’t have direct access to the view model; its data context is a Talk entity. (It would be reasonable to add a separate per-item view model for each talk in the list and make that the source instead, but for now we’re going to take a short cut.)
Private Sub Button_Click(ByVal sender As Object, ByVal e As RoutedEventArgs)
Dim btn As Button = CType(sender, Button)
Dim talk As Talk = CType(btn.DataContext, Talk)
Run the application. You should now find you can remove items from the schedule by right-clicking and then clicking the Remove button.
Add a line of code inside the Button_Click handler to hide the context menu. (Use the same code used in the popupContainer mouse button down handling to hide the menu.)