Using Commands with the RadContextMenu
Environment
| Product Version | 2026.1.415 |
| Product | RadContextMenu for WPF |
Description
Use RoutedUICommands with a RadContextMenu to move a selected ListBox item up or down through an MVVM view model.
Solution
Attach a RadContextMenu to a ListBox, expose the data and commands from a view model, select the right-clicked item, and register command bindings for ListBoxItem.
As the RadMenuItem implements the ICommandSource interface, you are able to use any kind of commands that inherit from the ICommand interface with it. This tutorial will show you how to use the RadContextMenu with RoutedUICommands combined with the MVVM pattern. Two commands are going to be exposed - one for moving an item in a ListBox up and one for moving an item down. The following things will come in focus:
Attaching a RadContextMenu to a ListBox control
Before getting to the commands, you have to prepare the UI on which they will get executed. In this tutorial a ListBox and a RadContextMenu are used.
Attach RadContextMenu to a ListBox
<ListBox xmlns:telerik="http://schemas.telerik.com/2008/xaml/presentation" x:Name="listBox">
<telerik:RadContextMenu.ContextMenu>
<telerik:RadContextMenu x:Name="radContextMenu">
</telerik:RadContextMenu>
</telerik:RadContextMenu.ContextMenu>
</ListBox>
Having the UI prepared, you have to add some data to it.
Populating the ListBox with data via a ViewModel
As the MVVM pattern should be used, you have to create a ViewModel for your UserControl, which will control its behavior. In it you will store the data which the View is using. Here is the declaration of the ViewModel class. It has a constructor, a method that initializes the items for the ListBox and an Items property, that stores them. Additionally create a SelectedItem property that will hold the selected item of the ListBox.
Define the ViewModel in C#
public class DataItem
{
public DataItem(string value)
{
this.Value = value;
}
public string Value { get; set; }
}
public class ExampleViewModel : INotifyPropertyChanged
{
private DataItem selectedItem;
public ExampleViewModel()
{
this.MoveUpCommand = new RoutedUICommand("Move Up", "MoveUp", typeof(ExampleViewModel));
this.MoveDownCommand = new RoutedUICommand("Move Down", "MoveDown", typeof(ExampleViewModel));
this.InitItems();
}
public event PropertyChangedEventHandler PropertyChanged;
public ObservableCollection<DataItem> Items
{
get;
set;
}
public DataItem SelectedItem
{
get
{
return this.selectedItem;
}
set
{
if (this.selectedItem != value)
{
this.selectedItem = value;
this.OnNotifyPropertyChanged("SelectedItem");
}
}
}
private void OnNotifyPropertyChanged(string propertyName)
{
if (this.PropertyChanged != null)
{
this.PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
}
}
private void InitItems()
{
ObservableCollection<DataItem> items = new ObservableCollection<DataItem>();
items.Add(new DataItem("Item 1"));
items.Add(new DataItem("Item 2"));
items.Add(new DataItem("Item 3"));
this.Items = items;
}
}
In the constructor of the UserControl you have to create an instance of the ViewModel, store it in a field and pass it as a DataContext of the entire UserControl.
Initialize the ViewModel in C#
private ExampleViewModel viewModel;
In the XAML you have to set the SelectedItem, the DisplayMemberPath and the ItemsSource properties of the ListBox in order to visualize the data.
Bind ListBox Data and Selection
<ListBox xmlns:telerik="http://schemas.telerik.com/2008/xaml/presentation"
x:Name="listBox"
DisplayMemberPath="Value"
ItemsSource="{Binding Items}"
SelectedItem="{Binding SelectedItem, Mode=TwoWay}">
<telerik:RadContextMenu.ContextMenu>
<telerik:RadContextMenu x:Name="radContextMenu">
</telerik:RadContextMenu>
</telerik:RadContextMenu.ContextMenu>
</ListBox>
Selecting the right-clicked ListBoxItem
Before continuing, there is one more thing to be done. When right-clicking to open the RadContextMenu, the clicked item should get selected, or if no item was clicked, the selection should be removed. This is done by handling the Opened event of the RadContextMenu.
Handle the Right-Clicked ListBoxItem
<ListBox xmlns:telerik="http://schemas.telerik.com/2008/xaml/presentation"
x:Name="listBox"
DisplayMemberPath="Value"
ItemsSource="{Binding Items}"
SelectedItem="{Binding SelectedItem, Mode=TwoWay}">
<telerik:RadContextMenu.ContextMenu>
<telerik:RadContextMenu x:Name="radContextMenu"
Opened="RadContextMenu_Opened">
</telerik:RadContextMenu>
</telerik:RadContextMenu.ContextMenu>
</ListBox>
Select the Right-Clicked ListBoxItem in C#
private void RadContextMenu_Opened(object sender, RoutedEventArgs e)
{
System.Windows.Controls.ListBoxItem item = this.radContextMenu.GetClickedElement<System.Windows.Controls.ListBoxItem>();
if (item != null)
{
this.listBox.SelectedItem = item.DataContext;
}
else
{
this.listBox.SelectedItem = null;
}
}
Preparing the RoutedUICommands
The next step is to create your commands. They will be host by the ViewModel.
Declare the RoutedUICommands in C#
public RoutedUICommand MoveUpCommand
{
get;
private set;
}
public RoutedUICommand MoveDownCommand
{
get;
private set;
}
Initialize them in the constructor of the ViewModel:
Initialize the RoutedUICommands in C#
this.MoveUpCommand = new RoutedUICommand("Move Up", "MoveUp", typeof(ExampleViewModel));
this.MoveDownCommand = new RoutedUICommand("Move Down", "MoveDown", typeof(ExampleViewModel));
Bind them in the View.
Bind the Commands to RadMenuItems
<ListBox xmlns:telerik="http://schemas.telerik.com/2008/xaml/presentation"
x:Name="listBox"
DisplayMemberPath="Value"
ItemsSource="{Binding Items}"
SelectedItem="{Binding SelectedItem, Mode=TwoWay}">
<telerik:RadContextMenu.ContextMenu>
<telerik:RadContextMenu x:Name="radContextMenu"
Opened="RadContextMenu_Opened">
<telerik:RadMenuItem Header="{Binding MoveUpCommand.Text}"
Command="{Binding MoveUpCommand}" />
<telerik:RadMenuItem Header="{Binding MoveDownCommand.Text}"
Command="{Binding MoveDownCommand}" />
</telerik:RadContextMenu>
</telerik:RadContextMenu.ContextMenu>
</ListBox>
You will also need methods that will get called when the command is executed. In the next section is explained how to connect the methods to the command. Here are sample methods for the two commands.
Implement the Move Commands in C#
public void MoveUp(object sender, ExecutedRoutedEventArgs e)
{
if (this.SelectedItem == null || this.Items.IndexOf(this.SelectedItem as DataItem) == 0)
{
return;
}
DataItem item = this.SelectedItem;
int index = this.Items.IndexOf(item as DataItem);
this.Items.Remove(item as DataItem);
this.Items.Insert(index - 1, item as DataItem);
this.SelectedItem = item;
}
public void MoveDown(object sender, ExecutedRoutedEventArgs e)
{
if (this.SelectedItem == null || this.Items.IndexOf(this.SelectedItem as DataItem) == this.Items.Count - 1)
{
return;
}
DataItem item = this.SelectedItem;
int index = this.Items.IndexOf(item as DataItem);
this.Items.Remove(item as DataItem);
this.Items.Insert(index + 1, item as DataItem);
this.SelectedItem = item;
}
Creating the CommandBindings
In order to use the commands in the UI you have to provide a CommandBinding for each of the commands. The CommandBinding binds the command to a method that is called when the command gets executed. The CommandBidnings get set via the CommandManager. As the CommandManager is called by the View you have to expose a method in your ViewModel that returns a collection of its CommandBindings.
Create CommandBindings in C#
public CommandBindingCollection GetCommandBindings()
{
CommandBindingCollection bindings = new CommandBindingCollection();
bindings.Add(new CommandBinding(this.MoveUpCommand, this.MoveUp));
bindings.Add(new CommandBinding(this.MoveDownCommand, this.MoveDown));
return bindings;
}
Setting the CommandBindings
In the View get the CommandBindingsCollection and set it through the CommandManager.
Register Command Bindings for ListBoxItem
public MainWindow()
{
this.InitializeComponent();
this.viewModel = new ExampleViewModel();
this.DataContext = this.viewModel;
CommandBindingCollection collection = this.viewModel.GetCommandBindings();
foreach (CommandBinding commandBinding in collection)
{
CommandManager.RegisterClassCommandBinding(typeof(ListBoxItem), commandBinding);
}
}