WPF XAML定义的菜单项重用开始工作,然后消失

WPF XAML定义的菜单项重用开始工作,然后消失,wpf,xaml,visual-studio-2013,menuitem,code-reuse,Wpf,Xaml,Visual Studio 2013,Menuitem,Code Reuse,下面的简单代码尝试重用Window.Resources中定义的菜单项,该菜单项位于两个单独的菜单上 <Window x:Class="WpfApplication.MainWindow" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:co

下面的简单代码尝试重用Window.Resources中定义的菜单项,该菜单项位于两个单独的菜单上

<Window x:Class="WpfApplication.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:collections="clr-namespace:System.Collections;assembly=mscorlib"
        Title="MainWindow" Height="350" Width="525">
  <Window.Resources>
    <collections:ArrayList x:Key="menuItemValues">
       <MenuItem Header="First"/>
       <MenuItem Header="Second"/>
       <MenuItem Header="Third"/>
    </collections:ArrayList>
    <MenuItem x:Key="menuItem" x:Shared="False"
              ItemsSource="{StaticResource menuItemValues}"
              Header="Shared menu item"/>
  </Window.Resources>
  <StackPanel>
    <Menu HorizontalAlignment="Left" VerticalAlignment="Top">
      <StaticResource ResourceKey="menuItem"/>
      <StaticResource ResourceKey="menuItem"/>
    </Menu>
  </StackPanel>
</Window>

这开始很好,当你第一次选择菜单时,一切看起来都很好。第一个菜单具有所需的菜单项

第二点也是:

但当您导航回第一个菜单时,菜单项将消失:

有人能解释一下为什么菜单不见了,还有什么方法可以让它工作吗

这是在调查另一个异常时发现的。我尝试使用上讨论的策略,它似乎解决了问题,直到您再次导航回菜单,它消失

我已在两台不同的机器上复制了此问题:

  • Win 10,VS2013 Ult V12.0.40629.00更新版5.NET V4.6.0138
  • Win 7,VS2013 Prem V12.0.31101.00更新版4.NET V4.5.51209

  • 发生这种情况的原因是,虽然顶级
    MenuItem
    x:Shared=“False”
    ,但集合中的
    MenuItem
    对象不是。它们在
    ArrayList
    集合中声明一次,然后在创建的
    menuItem
    对象的每个实例中重用

    要使代码正常工作,需要强制WPF创建新实例。一个选项是将
    x:Shared=“False”
    也应用于集合。例如:

    <Window x:Class="WpfApplication.MainWindow"
            xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
            xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
            xmlns:collections="clr-namespace:System.Collections;assembly=mscorlib"
            Title="MainWindow" Height="350" Width="525">
      <Window.Resources>
        <collections:ArrayList x:Key="menuItemValues" x:Shared="False">
           <MenuItem Header="First"/>
           <MenuItem Header="Second"/>
           <MenuItem Header="Third"/>
        </collections:ArrayList>
        <MenuItem x:Key="menuItem" x:Shared="False"
                  ItemsSource="{StaticResource menuItemValues}"
                  Header="Shared menu item"/>
      </Window.Resources>
      <StackPanel>
        <Menu HorizontalAlignment="Left" VerticalAlignment="Top">
          <StaticResource ResourceKey="menuItem"/>
          <StaticResource ResourceKey="menuItem"/>
        </Menu>
      </StackPanel>
    </Window>
    

    考虑到它的使用方式,您是否尝试了
    DynamicResource
    而不是Static?@ChrisW.-很好的建议-我刚刚尝试切换标记,结果导致
    XAMLParseException:只能在DependencyObject的DependencyProperty上设置“DynamicResourceExtension”。
    啊,是的,ItemSource是有意义的。嗯,我会试着在上面炖。哦,ffs,x:共享,掌心,+1很好的解释!
    <Window x:Class="WpfApplication.MainWindow"
            xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
            xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
            xmlns:s="clr-namespace:System;assembly=mscorlib"
            xmlns:collections="clr-namespace:System.Collections;assembly=mscorlib"
            Title="MainWindow" Height="350" Width="525">
      <Window.Resources>
        <collections:ArrayList x:Key="menuItemValues">
          <s:String>First</s:String>
          <s:String>Second</s:String>
          <s:String>Third</s:String>
        </collections:ArrayList>
        <MenuItem x:Key="menuItem" x:Shared="False"
                  ItemsSource="{StaticResource menuItemValues}"
                  Header="Shared menu item"/>
      </Window.Resources>
      <StackPanel>
        <Menu HorizontalAlignment="Left" VerticalAlignment="Top">
          <StaticResource ResourceKey="menuItem"/>
          <StaticResource ResourceKey="menuItem"/>
        </Menu>
      </StackPanel>
    </Window>