WPF XAML定义的MenuItem重用开始工作,然后消失 [英] WPF XAML defined MenuItem reuse starts working, then disappears
问题描述
以下简单代码尝试在两个单独的菜单上重用Window.Resources中定义的MenuItem.
The following simple code attempts to reuse a MenuItem defined in the Window.Resources on two separate Menus.
<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
This starts out great and when you first select the menus, all looks well. The first menu has the desired MenuItems,
第二个也是:
但是当您导航回到第一个菜单时,MenuItems消失了:
But when you navigate back to the first menu, the MenuItems disappear:
有人可以解释为什么菜单消失以及使该菜单起作用的方法吗?
Can someone explain why the menu disappears and a way to get this to work?
这是在调查另一个另一种方法中讨论的策略问题,它似乎可以解决问题,直到您再次导航回到菜单,然后它消失了.
This was discovered while investigating another SO question that was getting an exception. I tried to use a strategy discussed on another SO question and it seemed to solve the problem until you navigate back to the menu a second time and it disappears.
我已在2台单独的计算机上重现了此问题:
I have reproduced this issue on 2 separate machines:
- 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
对象的每个实例中重复使用.
This is happening because, while the top-level MenuItem
is x:Shared="False"
, the MenuItem
objects in your collection are not. They are declared once each in the ArrayList
collection, and then reused in each instance of the menuItem
object that's created.
要使代码正常工作,您需要强制WPF创建新实例.一种选择是将x:Shared="False"
也应用于集合.例如:
To get the code to work, you'll need to force WPF to create new instances. One option would be to apply the x:Shared="False"
to the collection as well. For example:
<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
模板行为.这使您可以重用集合本身(没有潜在的重用能力):
Of course, given that the items are simply given Header
values, you could just use the default MenuItem
templating behavior, by providing string
values instead of MenuItem
values. This allows you to reuse the collection itself (which has no underlying inability for reuse):
<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>
这篇关于WPF XAML定义的MenuItem重用开始工作,然后消失的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!