MenuItem上的图标不显示

时间:2017-02-23 16:52:55

标签: c# wpf image mvvm binding

我的WPF MVVM应用程序视图中有以下菜单

<Menu DockPanel.Dock="Top" >
    <MenuItem Header="File">
       <MenuItem Header="Open Video..." 
                         ToolTip="Open Video File..."
                         Caliburn:Message.Attach="[Event Click] = [Action OpenFile()]" 
                         InputGestureText="Ctrl + O">
          <MenuItem.Icon>
             <Image Width="16" Height="16"
                    Source="pack://application:,,,/Redactor;component/Resources/Pngs/open_document_black_16.png"/>
          </MenuItem.Icon>
       </MenuItem>
    </MenuItem>
    <MenuItem Header="Actions" ItemsSource="{Binding DynamMenuItems}">
        <MenuItem.Resources>
            <Image x:Key="FrozenImage" x:Shared="False" Source="{Binding Path=Image}"/>
        </MenuItem.Resources>
        <MenuItem.ItemContainerStyle>
            <Style TargetType="{x:Type MenuItem}" BasedOn="{StaticResource MetroMenuItem}">
                <!--<Setter Property="Icon" Value="{Binding Path=Image}"/>-->
                <Setter Property="Icon" Value="{StaticResource FrozenImage}"/>
                <Setter Property="Header" Value="{Binding Path=Text}"/>
                <Setter Property="Command" Value="{Binding Path=Command}"/>
            </Style>
        </MenuItem.ItemContainerStyle>
    </MenuItem>
</Menu>

在视图模型中,我有以下代码

private void BuildSelectionContextMenuItems()
{
    if (RedactionMenuItems == null)
        RedactionMenuItems = new BindableCollection<ContextMenuItem>();

    RedactionMenuItems.Clear();

    RedactionMenuItems.Add(new ContextMenuItem(
        Utils.GetImageFromUrl("pack://application:,,,/Redactor;component/Resources/Pngs/save_black_16.png"),
        "Save selection to video file...", 
        SaveSelectionToVideoFile));

    RedactionMenuItems.Add(new ContextMenuItem(
        "Commence auto-redaction on the selection...",
        PerformAutoRedactionOnSelection));

    RedactionMenuItems.Add(new ContextMenuItem(
        "Create matching audio-interval for selection",
        CreateAudioIntervalFromSelection));
}

private BindableCollection<ContextMenuItem> redactionMenuItems;
private ICommand saveSelectionToVideoFile;
private ICommand performAutoRedactionOnSelection;
private ICommand createAudioIntervalFromSelection;

public BindableCollection<ContextMenuItem> RedactionMenuItems
{
    get { return redactionMenuItems; }
    set
    {
        redactionMenuItems = value;
        NotifyOfPropertyChange(() => RedactionMenuItems);
    }
}

这可以工作并显示菜单项,但是当我将XAML代码更改为

时,图标不会显示
<Style TargetType="{x:Type MenuItem}" BasedOn="{StaticResource MetroMenuItem}">
    <Setter Property="Icon" Value="{Binding Path=Image}"/>
    <Setter Property="Header" Value="{Binding Path=Text}"/>
    <Setter Property="Command" Value="{Binding Path=Command}"/>
</Style>

它显示一次,然后消失。所以我尝试使用已知方法使用x:Shared="False"使图标不共享。但我无法理解为什么这不起作用,因为我也使用相同的RedactionMenuItems绑定到控件上的ContextMenu,这样可以正常工作。为什么这段代码不起作用?

ContextMenuItem类是

public class ContextMenuItem : PropertyChangedBase
{
    private Image image;
    private string text;
    private ICommand command;

    public ContextMenuItem(Image image, string text, ICommand command)
    {
        Image = image;
        Text = text;
        Command = command;
    }
    public ContextMenuItem(string text, ICommand command) : this(null, text, command) { }

    public Image Image
    {
        get { return image; }
        set
        {
            image = value;
            NotifyOfPropertyChange(() => Image);
        }
    }

    public string Text
    {
        get { return text; }
        set
        {
            text = value;
            NotifyOfPropertyChange(() => Text);
        }
    }

    public ICommand Command
    {
        get { return command; }
        set
        {
            command = value;
            NotifyOfPropertyChange(() => Command);
        }
    }
}

1 个答案:

答案 0 :(得分:1)

你的xaml部分:

Source

Image属性绑定到ViewModel中的Source对象。 ImageSource属性必须绑定到Image对象。所以,你有2个解决方案:

  1. 在ViewModel中,将ImageSource属性的类型更改为ImageSource类型。注意:您需要创建一个适当的BitmapImage对象才能返回。我使用var image1 = new Image(); image1.Source = new BitmapImage(new Uri("/Images/print.png", UriKind.Relative)); 就像这样:

    Converter
  2. 创建一个ImageSource对象,将您的图片属性转换为{{1}}对象。