C# WPF-菜单项缺少图标/图像

C# WPF-菜单项缺少图标/图像,c#,wpf,visual-studio-2010,icons,menuitem,C#,Wpf,Visual Studio 2010,Icons,Menuitem,我得到的菜单项图标只出现在最后一个菜单项上。 如果我窥探应用程序,则只有最后一个菜单项具有“图像输入”图标,而如果我调试所有菜单项,则所有菜单项似乎都具有“图像输入”图标。此外,如果我添加子菜单项,菜单项上的图标会在我打开子菜单时消失,最后一个子菜单会得到图标。。。有什么想法吗?另外,菜单项上的工具提示也不起作用。 Im使用caliburn micro和fluent ribbon控件 <ControlTemplate x:Key="dropDownButton">

我得到的菜单项图标只出现在最后一个菜单项上。 如果我窥探应用程序,则只有最后一个菜单项具有“图像输入”图标,而如果我调试所有菜单项,则所有菜单项似乎都具有“图像输入”图标。此外,如果我添加子菜单项,菜单项上的图标会在我打开子菜单时消失,最后一个子菜单会得到图标。。。有什么想法吗?另外,菜单项上的工具提示也不起作用。 Im使用caliburn micro和fluent ribbon控件

        <ControlTemplate x:Key="dropDownButton">
        <ef:DropDownButton Header="{Binding DisplayName}" 
                           ItemsSource="{Binding Items}" 
                           LargeIcon="{Binding LargeIconPath}" 
                           cm:Message.Attach="ClickAction()" 
                           ef:KeyTip.Keys="{Binding KeyTip}">
            <ef:DropDownButton.ItemContainerStyle>
                <Style TargetType="MenuItem">
                    <Setter Property="Header" 
                            Value="{Binding DisplayName}"/>
                    <Setter Property="Icon">
                        <Setter.Value>
                            <Image Source="{Binding Path=IconPath}"/>
                        </Setter.Value>
                    </Setter>
                    <Setter Property="ItemsSource" 
                            Value="{Binding Items}"/>
                    <Setter Property="cm:Message.Attach" 
                            Value="ClickAction()"/>
                    <Setter Property="ef:KeyTip.Keys" 
                            Value="{Binding KeyTip}"/>
                    <Setter Property="ToolTip">
                        <Setter.Value>
                            <ef:ScreenTip Title="{Binding DisplayName}"
                                          HelpTopic="ScreenTip help ..."
                                          Image="{Binding LargeIconPath}"
                                          Text="Text for ScreenTip"/>
                        </Setter.Value>
                    </Setter>
                </Style>
            </ef:DropDownButton.ItemContainerStyle>
            <ef:DropDownButton.ToolTip>
                <ef:ScreenTip Title="{Binding DisplayName}"
                              HelpTopic="ScreenTip help ..."
                              Image="{Binding LargeIconPath}"
                              Text="Text for ScreenTip"/>
            </ef:DropDownButton.ToolTip>
        </ef:DropDownButton>

您正在将
图标
属性设置为
样式中的
图像
控件。现在,只创建了一份
样式
,因此,只创建了一份
图像
。现在,任何控件一次只能有一个父控件。因此,当它被分配给最后一个
MenuItem
时,它将从以前的
MenuItem
控件中删除。要解决此问题,请使用
模板

不要设置
标题
属性,而是设置
标题模板

            <Setter Property="HeaderTemplate">
                <Setter.Value>
                    <DataTemplate>
                        <Grid>
                            <Grid.ColumnDefinitions>
                                <ColumnDefinition Width="Auto" />
                                <ColumnDefinition Width="*" />
                            </Grid.ColumnDefinitions>
                            <Image Grid.Column="0"
                                   Source="{Binding Path=IconPath}" />
                            <TextBlock Grid.Column="1"
                                       Text="{Binding DisplayName}" />
                        </Grid>
                    </DataTemplate>
                </Setter.Value>
            </Setter>

我不确定您正在使用的控件工具包公开了哪些属性。但是,我确信它们必须具有模板属性

执行此操作后,无需在样式中设置
图标
属性。

的工作原理如下:

       <DataTemplate x:Key="MenuItemHeaderTemplate">
        <Grid>
            <Grid.ColumnDefinitions>
                <ColumnDefinition Width="Auto" />
                <ColumnDefinition Width="*" />
            </Grid.ColumnDefinitions>
            <Image Grid.Column="0" Source="{Binding Path=IconPath}" />
            <Label Grid.Column="1" Content="{Binding DisplayName}" />               
        </Grid>
    </DataTemplate>


    <ControlTemplate x:Key="dropDownButton">
        <ef:DropDownButton Header="{Binding DisplayName}" 
                           ItemsSource="{Binding Items}" 
                           LargeIcon="{Binding LargeIconPath}" 
                           cm:Message.Attach="ClickAction()" 
                           ef:KeyTip.Keys="{Binding KeyTip}">
            <ef:DropDownButton.ItemContainerStyle>
                <Style TargetType="MenuItem">
                    <Setter Property="HeaderTemplate" Value="{StaticResource MenuItemHeaderTemplate}" />                                 
                    <Setter Property="ItemsSource" 
                            Value="{Binding Items}"/>
                    <Setter Property="cm:Message.Attach" 
                            Value="ClickAction()"/>
                    <Setter Property="ef:KeyTip.Keys" 
                            Value="{Binding KeyTip}"/>
                    <Setter Property="ToolTip">
                        <Setter.Value>
                            <ef:ScreenTip Title="{Binding DisplayName}"
                                          HelpTopic="ScreenTip help ..."
                                          Image="{Binding LargeIconPath}"
                                          Text="Text for ScreenTip"/>
                        </Setter.Value>
                    </Setter>
                </Style>
            </ef:DropDownButton.ItemContainerStyle>
            <ef:DropDownButton.ToolTip>
                <ef:ScreenTip Title="{Binding DisplayName}"
                              HelpTopic="ScreenTip help ..."
                              Image="{Binding LargeIconPath}"
                              Text="Text for ScreenTip"/>
            </ef:DropDownButton.ToolTip>
        </ef:DropDownButton>

我成功地在ResourceDictionary中使用了以下条目:

<!-- Define non-shared image to avoid loss of menu icons -->
<Image x:Key="MenuIconImage" Height="16" Width="16" x:Shared="false">
    <Image.Source>
        <DrawingImage Drawing="{Binding Icon}" />
    </Image.Source>
</Image>

<Style TargetType="{x:Type MenuItem}" BasedOn="{StaticResource {x:Type MenuItem}}">
    <Setter Property="Header" Value="{Binding DisplayName />
    <Setter Property="Icon" Value="{StaticResource MenuIconImage}" />
</Style>


由于某些原因,当图像是静态资源且x:Shared=false时,这种方法对我不起作用。只有最后一个菜单项显示图标。我尝试了StaticResource和DynamicResource。以下是我的解决方案:

public class MenuItemIconHelper
{
    #region ImageSource Icon

    public static readonly DependencyProperty IconProperty = DependencyProperty.RegisterAttached("Icon", typeof(ImageSource), typeof(MenuItemIconHelper), new PropertyMetadata(default(ImageSource), IconPropertyChangedCallback));

    private static void IconPropertyChangedCallback(DependencyObject obj, DependencyPropertyChangedEventArgs e)
    {
        var i = (MenuItem)obj;

        if (e.NewValue != null)
            i.Icon = new Image() {Source = (ImageSource)e.NewValue};
        else
            i.Icon = null;
    }

    public static void SetIcon(DependencyObject element, ImageSource value)
    {
        element.SetValue(IconProperty, value);
    }

    public static ImageSource GetIcon(DependencyObject element)
    {
        return (ImageSource)element.GetValue(IconProperty);
    }

    #endregion
}
样本:

<Style x:Key="CommandMenuItemStyle" TargetType="MenuItem">
<Setter Property="cb:MenuItemIconHelper.Icon" Value="car1.png" />
<Setter Property="Header" Value="{Binding Name}" />


<>我认为它比使用资源更可读,而且不需要改变MenuItem的HealEd模板。您还可以为ImageSource或Image实现一些缓存机制。

1。将现有文件…图像文件添加到资源中(如果您已有一个,请跳过它)

2.解决方案资源管理器中选择此图像文件

3.构建操作更改为资源

最后,您可以通过简单调用将此图像添加到XAML:

<Window.Resources>
    <ContextMenu x:Key="contextMenu" >
        <MenuItem Header="Restart" Name="menuItemRestart" Click="MenuItem_Click">
            <MenuItem.Icon>
                <Image Source="/Resources/restart.png"/>
            </MenuItem.Icon>
        </MenuItem>
        <Separator/>
        <MenuItem Header="Exit" Name="menuItemExit" Click="MenuItem_Click">
            <MenuItem.Icon>
                <Image Source="/Resources/window_close.png"/>
            </MenuItem.Icon>
        </MenuItem>
    </ContextMenu>
</Window.Resources>

结果:

在尝试使用这个时,我还不清楚。我收到错误:“System.Windows.Controls.Grid”不是Setter上“System.Windows.Controls.HeaderedContentControl.HeaderTemplate”属性的有效值。我的错误。您必须将其包装在
DataTemplate
.IMHO类似主题的解决方案:“是一个更好的解决方案。这对我很有用。我使用文本块和矩形作为图标,而不是图像