Wpf 菜单打开时,XAML ResourceDictionary中的图像在工具栏上消失

Wpf 菜单打开时,XAML ResourceDictionary中的图像在工具栏上消失,wpf,resourcedictionary,Wpf,Resourcedictionary,我已经开始将各种常见的图像移动到资源字典中,并注意到我的WPF应用程序中有一个奇怪的行为。如果图像用于菜单项和工具栏上的按钮,当我打开菜单时,按钮上的图像消失 <ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">

我已经开始将各种常见的
图像
移动到
资源字典
中,并注意到我的WPF应用程序中有一个奇怪的行为。如果
图像
用于
菜单项
工具栏
上的
按钮
,当我打开
菜单
时,
按钮
上的图像消失

<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
                    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
    <Image x:Key="NewImage"
           Source="/SomeApplication;component/Resources/NewDocumentHS.png"
           Stretch="None"/>
    <!-- ... -->
我假设这是
ResourceDictionary
中的资源警告,但我无法找到相应的修复方法。行为发生在
StaticResource
DynamicResource
中。它似乎也不受
ResourceDictionary
是否独立或是否与其他词典合并的影响。也没有其他资源共享该密钥


编辑:此外,向图像添加
呈现选项:Freeze=“True”
不会改变这种情况。

不能在多个位置使用图像控件,它只能在一个位置显示在可视树中,因此,如果对资源进行调用,则图像将从以前的所有者处抓取

编辑:
x:Shared=“False”
显然是一个比我下面所有建议都好的解决方案,我想知道为什么智能感知中没有显示如此重要的属性-_-


这种行为有点麻烦,我通常会为图像源预定义一个
IconStyle
BitMapImage
,但在我可能需要的地方为每个
MenuItem
创建新图像

您还可以为图标创建数据模板:

资源:

    <Style x:Key="IconImageStyle" TargetType="{x:Type Image}">
        <Setter Property="MaxWidth" Value="16"/>
        <Setter Property="MaxHeight" Value="16"/>
    </Style>
    <DataTemplate x:Key="Icon_Close_Template">
        <Image Style="{StaticResource IconImageStyle}"
               Source="pack://application:,,,/Images/Close.ico"/>
    </DataTemplate>
可以这样使用:

<Style x:Key="IconImageStyle" TargetType="{x:Type Image}">
    <Setter Property="MaxWidth" Value="16"/>
    <Setter Property="MaxHeight" Value="16"/>
</Style>
<Image x:Key="Icon_Close"  Style="{StaticResource IconImageStyle}" Source="pack://application:,,,/Images/Close.ico"/>
<!-- ... -->
<MenuItem Header="File">
    <MenuItem Header="Close" Icon="{m:Icon {StaticResource Icon_Close}}"/>
    <MenuItem Header="Close" Icon="{m:Icon {StaticResource Icon_Close}}"/>
</MenuItem>

图像类是可视的,因此它只能出现在可视树中的一个位置。因此,您不能在多个菜单项/按钮/等之间共享它

但是,您可以共享ImageSource(即Image.Source)值


在WPF中,我相信您可以使用=“False”强制WPF为每个请求创建一个新实例。

这听起来与我在Silverlight 4中使用路径样式的经历非常相似!运行时只渲染应用的资源的第一个实例,之后只是空的形状(在我的例子中是矢量图标):(我也没有找到任何解决办法……既然你提到了它是一个
Visual
,行为似乎是完全明显的!x:Shared位完全不明显。工作正常,非常感谢。
<Menu>
    <MenuItem Header="File">
        <MenuItem Header="Close">
            <MenuItem.Icon>
                <ContentPresenter ContentTemplate="{StaticResource Icon_Close_Template}"/>
            </MenuItem.Icon>
        </MenuItem>
        <MenuItem Header="Close">
            <MenuItem.Icon>
                <ContentPresenter ContentTemplate="{StaticResource Icon_Close_Template}"/>
            </MenuItem.Icon>
        </MenuItem>
    </MenuItem>
</Menu>
[MarkupExtensionReturnType(typeof(object))]
public class IconExtension : MarkupExtension
{
    private Image icon;
    public Image Icon
    {
        get { return icon; }
        set { icon = value; }
    }

    public IconExtension() { }
    public IconExtension(Image icon)
    {
        Icon = icon;
    }

    public override object ProvideValue(IServiceProvider serviceProvider)
    {
        if (Icon == null) throw new ArgumentNullException("Icon");
        return new Image() { Source = Icon.Source, Style = Icon.Style };
    }
}
<Style x:Key="IconImageStyle" TargetType="{x:Type Image}">
    <Setter Property="MaxWidth" Value="16"/>
    <Setter Property="MaxHeight" Value="16"/>
</Style>
<Image x:Key="Icon_Close"  Style="{StaticResource IconImageStyle}" Source="pack://application:,,,/Images/Close.ico"/>
<!-- ... -->
<MenuItem Header="File">
    <MenuItem Header="Close" Icon="{m:Icon {StaticResource Icon_Close}}"/>
    <MenuItem Header="Close" Icon="{m:Icon {StaticResource Icon_Close}}"/>
</MenuItem>