我正在尝试使用绑定创建一个动态菜单.我的viewmodel我有一个包含头和命令的对象列表.但是,它不工作.我认为问题在数据模板中.请参阅我的代码:
<Menu Background="{x:Null}" Grid.Row="0" Grid.Column="1" Panel.ZIndex="2" Width="865" Height="85" HorizontalAlignment="Left" ItemsSource="{Binding Path=MenuItems}"> <Menu.ItemTemplate> <HierarchicalDataTemplate DataType="MenuItemviewmodel" ItemsSource="{Binding Path=MenuItems}"> <MenuItem Header="{Binding Header}" Style="{DynamicResource MenuItemStyle1}" ItemsSource="{Binding Path=MenuItems}" Padding="10,12,10,0" Height="44.1" Margin="30,0" FontWeight="Bold"> <MenuItem.ItemsPanel> <ItemsPanelTemplate> <VirtualizingStackPanel Orientation="Horizontal"/> </ItemsPanelTemplate> </MenuItem.ItemsPanel> </MenuItem> <HierarchicalDataTemplate.ItemTemplate> <DataTemplate> <MenuItem Header="{Binding Header}" Style="{DynamicResource MenuItemStyle1}" Padding="0,8,0" Height="38"> </MenuItem> </DataTemplate> </HierarchicalDataTemplate.ItemTemplate> </HierarchicalDataTemplate> </Menu.ItemTemplate> </Menu>
结果只显示第一个菜单.子菜单没有显示,但是它们在那里,因为有孩子的菜单,箭头在菜单标题后打印.
有没有人会发现绑定有问题?还是任何建议?
MenuItems是MenuItemviewmodel对象的列表,它有一个名为MenuItems的MenuItemviewmodel对象(子菜单)的头和列表.
解决方法
对我来说,它与这个简单的模板一起工作:
<Menu.ItemContainerStyle> <Style TargetType="{x:Type MenuItem}"> <Setter Property="Command" Value="{Binding Command}" /> </Style> </Menu.ItemContainerStyle> <Menu.ItemTemplate> <HierarchicalDataTemplate DataType="{x:Type local:MenuItemviewmodel}" ItemsSource="{Binding Path=MenuItems}"> <TextBlock Text="{Binding Header}"/> </HierarchicalDataTemplate> </Menu.ItemTemplate>
这是完整的例子:
MainWindow.xaml:
<Window x:Class="WpfApplication14.MainWindow" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:local="clr-namespace:WpfApplication14" Title="MainWindow" Height="350" Width="525"> <DockPanel> <Menu DockPanel.Dock="Top" ItemsSource="{Binding MenuItems}"> <Menu.ItemContainerStyle> <Style TargetType="{x:Type MenuItem}"> <Setter Property="Command" Value="{Binding Command}" /> </Style> </Menu.ItemContainerStyle> <Menu.ItemTemplate> <HierarchicalDataTemplate DataType="{x:Type local:MenuItemviewmodel}" ItemsSource="{Binding Path=MenuItems}"> <TextBlock Text="{Binding Header}"/> </HierarchicalDataTemplate> </Menu.ItemTemplate> </Menu> <Grid> </Grid> </DockPanel> </Window>
MainWindow.xaml.cs:
using System; using System.Collections.ObjectModel; using System.Windows; using System.Windows.Input; namespace WpfApplication14 { public partial class MainWindow : Window { public ObservableCollection<MenuItemviewmodel> MenuItems { get; set; } public MainWindow() { InitializeComponent(); MenuItems = new ObservableCollection<MenuItemviewmodel> { new MenuItemviewmodel { Header = "Alpha" },new MenuItemviewmodel { Header = "Beta",MenuItems = new ObservableCollection<MenuItemviewmodel> { new MenuItemviewmodel { Header = "Beta1" },new MenuItemviewmodel { Header = "Beta2",MenuItems = new ObservableCollection<MenuItemviewmodel> { new MenuItemviewmodel { Header = "Beta1a" },new MenuItemviewmodel { Header = "Beta1b" },new MenuItemviewmodel { Header = "Beta1c" } } },new MenuItemviewmodel { Header = "Beta3" } } },new MenuItemviewmodel { Header = "Gamma" } }; DataContext = this; } } public class MenuItemviewmodel { private readonly ICommand _command; public MenuItemviewmodel() { _command = new Commandviewmodel(Execute); } public string Header { get; set; } public ObservableCollection<MenuItemviewmodel> MenuItems { get; set; } public ICommand Command { get { return _command; } } private void Execute() { // (NOTE: In a view model,you normally should not use MessageBox.Show()). MessageBox.Show("Clicked at " + Header); } } public class Commandviewmodel : ICommand { private readonly Action _action; public Commandviewmodel(Action action) { _action = action; } public void Execute(object o) { _action(); } public bool CanExecute(object o) { return true; } public event EventHandler CanExecuteChanged { add { } remove { } } } }
结果窗口如下所示: