2016-03-08 17 views
6

Der folgende einfache Code versucht, ein MenuItem wieder zu verwenden, das in den Window.Resources in zwei separaten Menüs definiert ist.WPF XAML definiert MenuItem Wiederverwendung beginnt zu arbeiten, verschwindet dann

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

Das beginnt großartig und wenn Sie zuerst die Menüs auswählen, sieht alles gut aus. Das erste Menü die gewünschten MenuItems,

enter image description here

Das Gleiche gilt für die zweite:

enter image description here

Aber wenn Sie zurück zum ersten Menü navigieren, die MenuItems verschwinden:

enter image description here

Kann jemand erklären, warum das Menü verschwindet und a Weg, um das zum Laufen zu bringen?

Dies wurde während der Untersuchung einer anderen SO question entdeckt, die eine Ausnahme bekam. Ich habe versucht, eine Strategie zu verwenden, die unter another SO question diskutiert wurde, und es schien das Problem zu lösen, bis Sie ein zweites Mal zum Menü zurückkehren und es verschwindet.

ich dieses Problem auf zwei getrennten Maschinen reproduziert:

  1. Win 10, VS2013 Ult V12.0.40629.00 Update 5, .NET V4.6.0138
  2. Win 7, VS2013 Prem V12.0.31101. 00 Update 4, .NET V4.5.51209
+0

Bedenkt man, wie es verwendet wird, haben Sie versucht, 'DynamicResource' statt Static? –

+0

@ChrisW. - guter Vorschlag - Ich habe gerade versucht, die Tags zu wechseln, und es verursachte 'XAMLParseException: Eine 'DynamicResourceExtension' kann nur für eine DependencyProperty eines DependencyObject gesetzt werden. – Taterhead

+0

Ah ja, ItemSource, macht Sinn. Hmm, ich werde versuchen, es zu schmoren. –

Antwort

7

Dies geschieht, weil, während die Top-Level-MenuItemx:Shared="False" ist, die MenuItem Objekte in Ihrer Sammlung nicht. Sie werden jeweils einmal in der ArrayList-Auflistung deklariert und dann in jeder Instanz des erstellten Objekts menuItem erneut verwendet.

Damit der Code funktioniert, müssen Sie WPF erzwingen, neue Instanzen zu erstellen. Eine Option wäre, die x:Shared="False" auch auf die Sammlung anzuwenden. Zum Beispiel:

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

Natürlich gegeben, dass die Gegenstände einfach Header Werte angegeben, können Sie nur das Standardverhalten MenuItem Templat verwenden, durch string Werte statt MenuItem Werte bereitstellt. Auf diese Weise können Sie die Sammlung selbst (die keine zugrunde liegenden Unfähigkeit zur Wiederverwendung hat) wieder zu verwenden:

<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: geteilt, Gesichtspalme, +1 großartige Erklärung! –