2016-03-08 17 views
6

Il seguente codice semplice tenta di riutilizzare un MenuItem definito in Window.Resources su due menu separati.WPF XAML definito MenuItem riutilizzo inizia a funzionare, quindi scompare

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

Questo si avvia alla grande e quando si selezionano per la prima volta i menu, tutto sembra a posto. Il primo menu ha le MenuItems desiderati,

enter image description here

Così fa il secondo:

enter image description here

Ma quando si passa di nuovo al primo menu, i MenuItems scompaiono:

enter image description here

Qualcuno può spiegare perché il menu scompare e un modo per farlo funzionare?

Questo è stato rilevato durante l'indagine su un altro SO question che stava ottenendo un'eccezione. Ho provato a utilizzare una strategia discussa su another SO question e sembrava risolvere il problema fino a quando non si torna al menu una seconda volta e scompare.

ho riprodotto questo problema su 2 macchine separate:

  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

Considerando come è in uso, non si tenta 'DynamicResource' invece di statico? –

+0

@ Chrishr. - buon suggerimento - Ho appena provato a cambiare i tag e ha causato 'XAMLParseException: A 'DynamicResourceExtension' può essere impostato solo su DependencyProperty di DependencyObject. – Taterhead

+0

Ah sì, ItemSource, ha senso. Hmm, ci proverò e lo spezzerò. –

risposta

7

Questo accade perché, mentre il livello superiore MenuItem è x:Shared="False", gli MenuItem oggetti nella vostra collezione non lo sono. Vengono dichiarati una volta ciascuno nella raccolta ArrayList e quindi riutilizzati in ogni istanza dell'oggetto menuItem creato.

Per far funzionare il codice, è necessario forzare WPF per creare nuove istanze. Un'opzione consisterebbe nell'applicare anche la collezione x:Shared="False" alla raccolta. Per esempio:

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

Naturalmente, dato che gli elementi sono semplicemente dato Header valori, si potrebbe utilizzare il comportamento di template di default MenuItem, fornendo string valori invece di MenuItem valori. Questo consente di riutilizzare la raccolta stessa (che non ha l'incapacità di fondo per il riutilizzo):

<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: condiviso, faccia palm, +1 grande spiegazione! –

Problemi correlati