如何动态绑定和静态添加菜单项?涉及编程相关内容。

29

我将 MenuItem 的 ItemsSource 绑定到 ViewModel 中的 ObservableCollection。以下是我的 XAML 代码:

<MenuItem Header="_View"
          ItemsSource="{Binding Windows}">
  <MenuItem.ItemContainerStyle>
    <Style>
      <Setter Property="MenuItem.Header"
              Value="{Binding Title}" />
    </Style>
  </MenuItem.ItemContainerStyle>
</MenuItem>

这部分功能很棒,但现在我还想将一些静态的菜单项添加到同一个视图菜单项中,并用分隔符隔开。就像这样,尽管我知道这样做不起作用,因为我不能设置两次项目。

<MenuItem Header="_View"
          ItemsSource="{Binding Windows}">
  <MenuItem.ItemContainerStyle>
    <Style>
      <Setter Property="MenuItem.Header"
              Value="{Binding Title}" />
    </Style>
  </MenuItem.ItemContainerStyle>
  <Separator />
  <MenuItem Header="item 1" />
  <MenuItem Header="item 2" />
</MenuItem>

目前,我已经通过像这样向MenuItem添加另一个级别来创建了一个解决方法:

<MenuItem Header="_View">
  <MenuItem Header="Windows"
            ItemsSource="{Binding Windows}">
    <MenuItem.ItemContainerStyle>
      <Style>
        <Setter Property="MenuItem.Header"
                Value="{Binding Title}" />
      </Style>
    </MenuItem.ItemContainerStyle>
  </MenuItem>
  <MenuItem Header="Load Layout" />
  <MenuItem Header="Save Layout" />
</MenuItem>
这很好运作,但如果可能的话,我宁愿不要子菜单。哦,而且我更喜欢在XAML中做这个而不是在代码后面。有什么想法吗?

这个方案可以,但如果有可能,我不想要子菜单。另外,我也更希望在XAML中实现而不是在代码后台。有什么建议吗?


也许你可以使用CompositeCollection将VM中的集合与XAML定义的集合“统一”起来。 - Federico Berasategui
1个回答

51

您可以使用CompositeCollection来实现这一点,它可以将不同的集合和静态项组合在XAML中。

示例:

XAML:

示例:

XAML:

<Window x:Class="WpfApplication8.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        Title="MainWindow" Height="233" Width="143" Name="UI">
    <Window.Resources>
        <CollectionViewSource Source="{Binding ElementName=UI, Path=Windows}" x:Key="YourMenuItems"/>
     </Window.Resources>

    <Grid DataContext="{Binding ElementName=UI}">
        <Menu Height="24" VerticalAlignment="Top">
            <MenuItem Header="_View" >
                <MenuItem Header="Windows">
                    <MenuItem.ItemsSource>
                        <CompositeCollection>
                            <CollectionContainer Collection="{Binding Source={StaticResource YourMenuItems}}" />
                            <MenuItem Header="Menu Item 1" />
                            <MenuItem Header="Menu Item 2" />
                            <MenuItem Header="Menu Item 3" />
                        </CompositeCollection>
                    </MenuItem.ItemsSource>
                    <MenuItem.ItemContainerStyle>
                        <Style>
                            <Setter Property="MenuItem.Header" Value="{Binding Title}"/>
                        </Style>
                    </MenuItem.ItemContainerStyle>
                </MenuItem>
            </MenuItem>
        </Menu>
    </Grid>
</Window>

代码

public partial class MainWindow : Window
{
    private ObservableCollection<MyObject> _windows = new ObservableCollection<MyObject>();

    public MainWindow()
    {
        InitializeComponent();
        Windows.Add(new MyObject { Title = "Collection Item 1" });
        Windows.Add(new MyObject { Title = "Collection Item 2" });
    }

    public ObservableCollection<MyObject> Windows
    {
        get { return _windows; }
        set { _windows = value; }
    }
}

public class MyObject
{
    public string Title { get; set; }
}

结果:

enter image description here


{Binding ElementName=UI} 这个东西是干什么用的? - Pyritie
1
如果我绑定了MenuItemsSource(而不是其中的一个MenuItem),那该怎么办?我无法让ItemContainerStyle起作用,因为我设置了Menu.ItemContainerStyle,这是错误的... - JobaDiniz

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接