Binding to Dynamic Data
The data displayed in the RadContextMenu has a hierarchical structure (similar to the RadTreeView). This means that each item may come with a set of items on its own. For that reason you have to use the ItemContainerStyle. This tutorial will walk you through the most important steps in creating, configuring and applying ItemContainerStyle to your RadContextMenu.
Preparing the Data
This tutorial uses the following sample class:
Example 1: The MenuItem class
public class MenuItem
{
public MenuItem()
{
this.SubItems = new ObservableCollection<MenuItem>();
}
public string Text
{
get;
set;
}
public Uri IconUrl
{
get;
set;
}
public bool IsSeparator
{
get;
set;
}
public ICommand Command
{
get;
set;
}
public ObservableCollection<MenuItem> SubItems
{
get;
set;
}
}
Public Class MenuItem
Public Sub New()
Me.SubItems = New ObservableCollection(Of MenuItem)()
End Sub
Public Property Text() As String
Public Property IconUrl() As Uri
Public Property IsSeparator() As Boolean
Public Property Command() As ICommand
Public Property SubItems() As ObservableCollection(Of MenuItem)
End Class
The MenuItem class holds the information for the menu items.
Text: Represents the text value for the item.
IconUrl: Represents the URL of the image that represents the icon of the menu item.
SubItems: A collection of the sub menu items of the current menu item.
IsSeparator: Indicates whether the item is a separator.
To learn more about the separator items and the RadMenuItems, please take a look at the RadMenu help content.
Next, we create a method to create the sample data to populate the RadContextMenu:
Example 2: Generating menu items
public ObservableCollection<MenuItem> GetMenuItems()
{
ObservableCollection<MenuItem> items = new ObservableCollection<MenuItem>();
MenuItem copyItem = new MenuItem()
{
IconUrl = new Uri("Images/copy.png", UriKind.Relative),
Text = "Copy",
};
items.Add(copyItem);
MenuItem pasteItem = new MenuItem()
{
IconUrl = new Uri("Images/paste.png", UriKind.Relative),
Text = "Paste",
};
items.Add(pasteItem);
MenuItem cutItem = new MenuItem()
{
IconUrl = new Uri("Images/cut.png", UriKind.Relative),
Text = "Cut",
};
items.Add(cutItem);
MenuItem separatorItem = new MenuItem()
{
IsSeparator = true
};
items.Add(separatorItem);
MenuItem selectAllItem = new MenuItem()
{
Text = "Select All"
};
items.Add(selectAllItem);
return items;
}
Public Function GetMenuItems() As ObservableCollection(Of MenuItem)
Dim items As New ObservableCollection(Of MenuItem)()
Dim copyItem As New MenuItem() With {.IconUrl = New Uri("Images/copy.png", UriKind.Relative), .Text = "Copy"}
items.Add(copyItem)
Dim pasteItem As New MenuItem() With {.IconUrl = New Uri("Images/paste.png", UriKind.Relative), .Text = "Paste"}
items.Add(pasteItem)
Dim cutItem As New MenuItem() With {.IconUrl = New Uri("Images/cut.png", UriKind.Relative), .Text = "Cut"}
items.Add(cutItem)
Dim separatorItem As New MenuItem() With {.IsSeparator = True}
items.Add(separatorItem)
Dim selectAllItem As New MenuItem() With {.Text = "Select All"}
items.Add(selectAllItem)
Return items
End Function
Finally, set the generated collection as the ItemsSource of the control.
Example 3: Setting RadContextMenu's ItemsSource
InitializeComponent();
this.radContextMenu.ItemsSource = this.GetMenuItems();
InitializeComponent()
Me.radContextMenu.ItemsSource = Me.GetMenuItems()
Creating and Applying the ItemContainerStyle
In order to visualize the data in the RadContextMenu control you have to use a ItemContainerStyle property. Here is a sample Style used to visualize the items in the RadContextMenu control.
Example 4: The custom menu item style
<Style x:Key="MenuItemStyle" TargetType="telerik:RadMenuItem">
<Setter Property="Icon" Value="{Binding IconUrl}"/>
<Setter Property="IconTemplate">
<Setter.Value>
<DataTemplate>
<Image Source="{Binding}" Stretch="None"/>
</DataTemplate>
</Setter.Value>
</Setter>
<Setter Property="IsSeparator" Value="{Binding IsSeparator}"/>
<Setter Property="Header" Value="{Binding Text}"/>
<Setter Property="ItemsSource" Value="{Binding SubItems}"/>
<Setter Property="Command" Value="{Binding Command}"/>
</Style>
If you use NoXaml assemblies, set the BasedOn property to the default style:
BasedOn="{StaticResource RadMenuItemStyle}"
.
When setting the ItemTemplate or ItemContainerStyle properties of the RadContextMenu, they will get inherited in the hierarchy, unless they are not explicitly set.
In order to use the created style with RadContextMenu control, you have to now set its ItemContainerStyle property.
Example 5: Setting the ItemContainerStyle
<TextBox Width="200" VerticalAlignment="Center" ContextMenu="{x:Null}" >
<telerik:RadContextMenu.ContextMenu>
<telerik:RadContextMenu x:Name="radContextMenu" ItemContainerStyle="{StaticResource MenuItemStyle}" />
</telerik:RadContextMenu.ContextMenu>
</TextBox>
Figure 1 demonstrates the final result.