2016-03-08 9 views
6

次の単純なコードは、Window.Resourcesで定義されたMenuItemを2つの別々のメニューに再利用しようとします。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> 

これは素晴らしいことです。最初にメニューを選択すると、すべてがうまく見えます。

enter image description here

しかし、あなたは戻って最初のメニューに移動するとき、のMenuItemが消える::

enter image description here最初のメニューは、だから、二を行い

enter image description here

、希望のMenuItemを持っています

誰かがメニューが消える理由を説明できますか?これを動作させる方法は?

これは例外を取得していた別のSO questionを調査中に発見されました。私はanother SO questionで議論された戦略を使用しようとしたが、メニューに戻ると消えるまで問題を解決するように見えた。

私は2台の別々のマシン上でこの問題を再現しています

  1. 勝利10、VS2013 ULT V12.0.40629.00アップデート5、.NET V4.6.0138
  2. 勝利7、VS2013プレムV12.0.31101。 00更新4、.NET V4.5.51209
+0

スタティックの代わりに 'DynamicResource'を試しましたか? –

+0

@ChrisW。 - 良い提案 - タグの切り替えを試みたところ、XAMLParseExceptionが発生しました:「DynamicResourceExtension」はDependencyObjectのDependencyPropertyにしか設定できません。 – Taterhead

+0

ああ、ItemSourceは意味があります。うーん、私はそれを試してみるだろう。 –

答えて

7

これが起こっているトップレベルMenuItemx:Shared="False"ている間、ので、あなたのコレクション内のMenuItemのオブジェクトではありません。それらはArrayListコレクションで1回ずつ宣言され、作成されたmenuItemオブジェクトの各インスタンスで再利用されます。

コードを機能させるには、新しいインスタンスを作成するためにWPFを強制する必要があります。 1つのオプションは、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値を与えていることを考えると、あなただけのstring値の代わりに、MenuItem値を提供することで、デフォルト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

ああffs、x:共有、顔の手のひら、+1素晴らしい説明! –

関連する問題