2016-03-08 7 views
6

Следующий простой код пытается повторно использовать MenuItem, определенный в Window.Resources на двух отдельных меню.WPF XAML определено MenuItem повторное использование начинает работать, затем исчезает

<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> 

Это начинается отлично, и когда вы впервые выбираете меню, все выглядит хорошо. Первое меню имеет желательные MenuItems,

enter image description here

Так делает второй:

enter image description here

Но когда вы переходите обратно в первое меню, то MenuItems исчезают:

enter image description here

Может кто-нибудь объяснить, почему меню исчезает, и способ заставить это работать?

Это было обнаружено при исследовании другого SO question, который получал исключение. Я попытался использовать стратегию, обсуждавшуюся на another SO question, и, похоже, она решила проблему, пока вы снова не вернетесь в меню и не исчезнет.

я воспроизвел эту проблему на 2 отдельных машинах:

  1. Win 10, VS2013 п.Ульт V12.0.40629.00 Обновление 5, .NET V4.6.0138
  2. Win 7, VS2013 Прет V12.0.31101. 00 Update 4, .NET V4.5.51209
+0

Учитывая, как он используется, вы пытались использовать DynamicResource вместо Static? –

+0

@ChrisW. - Хорошее предложение - я просто попытался переключить теги, и это вызвало «XAMLParseException:« DynamicResourceExtension »можно установить только на DependencyProperty DependencyObject.' – Taterhead

+0

Ah yea, ItemSource, имеет смысл. Хм, я попробую и туша на нем. –

ответ

7

Это происходит потому, что, в то время как верхний уровень 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> 

Конечно, учитывая, что элементы просто даны Header значения, вы могли бы просто использовать поведение по умолчанию шаблонного MenuItem, предоставляя string значения вместо MenuItem значений. Это позволяет повторно использовать саму коллекцию (которая не имеет оснований для повторного использования):

<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> 
+0

Oh ffs, x: общий, ладонь на лице, +1 отличное объяснение! –