I’d like to be able to create dynamic menus associated with certain object. Let’s say, I will have 3 listview container with one style where I also have a Menu. I need to generate different menu items from collection of the RoutetUICommands in relation on each listview. I was trying to solve this puzzle but took me a while and still have trouble making it work. I need to generate object specific menus, an unique menu for each listview. Any ideas are highly appreciated. Thank you!
XAML:
<Window
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:Microsoft_Windows_Themes="clr-namespace:Microsoft.Windows.Themes;assembly=PresentationFramework.Aero"
x:Class="DynamicMenu.MainWindow"
x:Name="Window"
Title="MainWindow"
Width="640" Height="480">
<Window.Resources>
<Style x:Key="ListViewStyleTask" TargetType="{x:Type ListView}">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type ListView}">
<Grid>
<Menu x:Name="mainMenu">
<MenuItem x:Name="menuItem" Header="Tasks" ItemsSource="{Binding Commands}" >
<MenuItem.ItemContainerStyle>
<Style TargetType="{x:Type MenuItem}">
<Setter Property="Command" Value="{Binding}" />
<Setter Property="Header" Value="{Binding Path=Text}" />
<Setter Property="CommandParameter" Value="{Binding Path=Parameter}" />
</Style>
</MenuItem.ItemContainerStyle>
</MenuItem>
</Menu>
</Grid>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</Window.Resources>
<Grid x:Name="LayoutRoot">
<ListView x:Name="Container1" HorizontalAlignment="Left" Height="100" VerticalAlignment="Top" Width="100" Style="{DynamicResource ListViewStyleTask}">
<ListView.View>
<GridView>
<GridViewColumn/>
</GridView>
</ListView.View>
</ListView>
<ListView x:Name="Container2" HorizontalAlignment="Left" Height="100" VerticalAlignment="Top" Width="100" Style="{DynamicResource ListViewStyleTask}">
<ListView.View>
<GridView>
<GridViewColumn/>
</GridView>
</ListView.View>
</ListView>
<ListView x:Name="Container3" HorizontalAlignment="Left" Height="100" VerticalAlignment="Top" Width="100" Style="{DynamicResource ListViewStyleTask}">
<ListView.View>
<GridView>
<GridViewColumn/>
</GridView>
</ListView.View>
</ListView>
</Grid>
I have added some commands which I need to associate to 3 different Listviews:
public partial class MainWindow : Window
{
// Container 1
public static RoutedUICommand NameCommand = new RoutedUICommand("Name", "NameCommand", typeof(MainWindow));
public static RoutedUICommand StreetCommand = new RoutedUICommand("Street", "StreetCommand", typeof(MainWindow));
public static RoutedUICommand GroupCommand = new RoutedUICommand("Add to Group", "AddGroup", typeof(MainWindow));
// Container 2
public static RoutedUICommand ViewDetailsCommand = new RoutedUICommand("View Details", "ViewDetailsCommand", typeof(MainWindow));
// Container 3
public static RoutedUICommand StartCommand = new RoutedUICommand("Start", "StartCommand", typeof(MainWindow));
public static RoutedUICommand StopCommand = new RoutedUICommand("Stop", "StopCommand", typeof(MainWindow));
public static RoutedUICommand LoadCommand = new RoutedUICommand("Load", "LoadCommand", typeof(MainWindow));
public MainWindow()
{
this.InitializeComponent();
// Insert code required on object creation below this point.
}
}
}
You need to define a structure to group the data as you need in your control template. Something like this,
Have 3 members of
CommandCollectioneach one having its commands and then assign those as datacontext to the ListViewsUpdated,
After declaring the above structure you declare 3 members,
Fill these members,
Set data context,
Update your control template to specify menu item command binding,
Updated
XAML
Code behind
Other classes
I Hope now you get it working.
Updated for RoutedUICommand description,
The idea should be to have these menu items in the outer container (like shell) which will have other pages in it (like a frame/canvas), like for example if you see MS Visual Studio the menu items (Save) are part of the application shell and the files openeed are within the shell (shell has a container tabcontrol maybe, where the files are loaded as they are opened). So the routed commands (Save) are defined by the application shell and all the other pages inside the shell’s container add those commands in there command binding collection (
this.CommandBindings.Add(cmdname, actionname, predicatename)) so each page performs its own respective action and the command is invoked for them only when they are in focus.