Workarounds for supporting MVVM in the Silverlight ContextMenu service
Posted
by cibrax
on ASP.net Weblogs
See other posts from ASP.net Weblogs
or by cibrax
Published on Mon, 31 Jan 2011 15:27:33 GMT
Indexed on
2011/01/31
23:26 UTC
Read the original article
Hit count: 269
.NET
|Silverlight
As I discussed in my last post, some of the Silverlight controls does not support MVVM quite well out of the box without specific customizations. The Context Menu is another control that requires customizations for enabling data binding on the menu options. There are a few things that you might want to expose as view model for a menu item, such as the Text, the associated icon or the command that needs to be executed. That view model should look like this,
public class MenuItemModel
{
public string Name { get; set; }
public ICommand Command { get; set; }
public Image Icon { get; set; }
public object CommandParameter { get; set; }
}
This is how you can modify the built-in control to support data binding on the model above,
public class CustomContextMenu : ContextMenu
{
protected override DependencyObject GetContainerForItemOverride()
{
CustomMenuItem item = new CustomMenuItem();
Binding commandBinding = new Binding("Command");
item.SetBinding(CustomMenuItem.CommandProperty, commandBinding);
Binding commandParameter = new Binding("CommandParameter");
item.SetBinding(CustomMenuItem.CommandParameterProperty, commandParameter);
return item;
}
}
public class CustomMenuItem : MenuItem
{
protected override DependencyObject GetContainerForItemOverride()
{
CustomMenuItem item = new CustomMenuItem();
Binding commandBinding = new Binding("Command");
item.SetBinding(CustomMenuItem.CommandProperty, commandBinding);
return item;
}
}
Once you applied that change in the control, you can define it in your XAML like this.
<toolkit:ContextMenuService.ContextMenu>
<e:CustomContextMenu ItemsSource="{Binding MenuItems}">
<e:CustomContextMenu.ItemTemplate>
<DataTemplate>
<StackPanel Orientation="Horizontal" >
<ContentPresenter Margin="0 0 4 0" Content="{Binding Icon}" />
<TextBlock Margin="0" Text="{Binding Name, Mode=OneWay}" FontSize="12"/>
</StackPanel>
</DataTemplate>
</e:CustomContextMenu.ItemTemplate>
</e:CustomContextMenu>
</toolkit:ContextMenuService.ContextMenu>
The property MenuItems associated to the “ItemsSource” in the parent model just returns a list of supported options (menu items) in the context menu.
this.menuItems = new MenuItemModel[]
{
new MenuItemModel
{
Name = "My Command",
Command = new RelayCommand(OnCommandClick),
Icon = ImageLoader.GetIcon("command.png")
}
};
The only problem I found so far with this approach is that the context menu service does not support a HierarchicalDataTemplate in case you want to have an hierarchy in the context menu (MenuItem –> Sub menu items), but I guess we can live without that.
© ASP.net Weblogs or respective owner