3
votes

I have a problem with Menu Item Command Binding. I have used MVVM pattern When I use right click, the menu appears. But when I click on the menu item doesn't work. Do you know why? Thanks

Here is the XAML:

    <UserControl x:Class="PlotView.ViewModel.PlotViewControl"
             xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
             xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
             xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
             xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 
             xmlns:oxy="http://oxyplot.org/wpf"
             mc:Ignorable="d" 
             xmlns:diagnostics="clr-namespace:System.Diagnostics;assembly=WindowsBase"
             d:DesignHeight="400" d:DesignWidth="600"
             x:Name="theViewName">

    <UserControl.Resources>
    </UserControl.Resources>

    <GroupBox  Name="GB" Header="Graphs"  HorizontalAlignment="Stretch" VerticalAlignment="Stretch"  BorderThickness="0">
        <ListView Name="PlotLista"    SelectedIndex="{Binding SelectedValue}" ItemsSource="{Binding PlotModelList}" HorizontalAlignment="Stretch" VerticalAlignment="Stretch" >
            <ListView.ItemTemplate>
                <DataTemplate>
                    <oxy:Plot  MinHeight="260" Height="Auto"   IsRendering="True" FontStyle="Normal" FontFamily="Arial" FontSize="8"  VerticalContentAlignment="Top"  HorizontalContentAlignment="Left" Width="{Binding RelativeSource={RelativeSource Mode=FindAncestor, AncestorType={x:Type UserControl}}, Path=ActualWidth}"  Model="{Binding }">
                        <oxy:Plot.ContextMenu>
                            <ContextMenu>
                                <MenuItem Header="Export to PNG" Command="{Binding DataContext.SavePNG, ElementName=theViewName}"/>
                            </ContextMenu>
                        </oxy:Plot.ContextMenu>
                    </oxy:Plot>
                </DataTemplate>
            </ListView.ItemTemplate>
        </ListView>
    </GroupBox>
</UserControl>

Here are a small portion of ViewModel:

 #region Fields
        private readonly DelegateCommand _menuClick=new DelegateCommand(this.MenuItemClick);
  #endregion

  #region Command
 public ICommand SavePNG
 {
   get { return this._menuClick; }
 }
  #endregion

 private void MenuItemClick()
{
   // some code here
}

Error:

System.Windows.Data Error: 40 : BindingExpression path error: 'SavePNG' property not found on 'object' ''PlotModel' (HashCode=15385318)'. BindingExpression:Path=SavePNG; DataItem='PlotModel' (HashCode=15385318); target element is 'MenuItem' (Name=''); target property is 'Command' (type 'ICommand')

3
is SavePNG command on the same ViewModel which contains PlotModelList?Krishna
Yes. public partial class PlotViewControl { public PlotViewControl() { InitializeComponent(); this.DataContext = new PlotViewModel(); }Adrian

3 Answers

0
votes

Your binding is trying to find SavePNG on your Item, not your ViewModel.

Instead, give your view an x:Name, or a Name, and use the following binding instead:

{Binding DataContext.SavePNG, ElementName=theViewName}
0
votes

Assuming that SaveCommand is on the same ViewModel which contains your collection.

ContextMenus are a little different in wpf as they are not part of the visual tree of the control. As such they cannot 'see' any elements by relative source or by elementnames.

A little cheat is to use the PlacementTarget property and get the datacontext with that. Change your ListView to below to make it work. Notice the tag property on the ListView and the DataContext property on the ContextMenu.

<ListView Name="PlotLista"    SelectedIndex="{Binding SelectedValue}" ItemsSource="{Binding PlotModelList}" HorizontalAlignment="Stretch" VerticalAlignment="Stretch" Tag="{Binding DataContext,ElementName=theViewName}">
            <ListView.ItemTemplate>
                <DataTemplate>
                    <oxy:Plot  MinHeight="260" Height="Auto"   IsRendering="True" FontStyle="Normal" FontFamily="Arial" FontSize="8"  VerticalContentAlignment="Top"  HorizontalContentAlignment="Left" Width="{Binding RelativeSource={RelativeSource Mode=FindAncestor, AncestorType={x:Type UserControl}}, Path=ActualWidth}"  Model="{Binding }">
                        <oxy:Plot.ContextMenu>
                            <ContextMenu DataContext="{Binding PlacementTarget.Tag, RelativeSource={RelativeSource Self}}">
                                <MenuItem Header="Export to PNG" Command="{Binding SavePNG}"/>
                            </ContextMenu>
                        </oxy:Plot.ContextMenu>
                    </oxy:Plot>
                </DataTemplate>
            </ListView.ItemTemplate>
        </ListView>
0
votes

This wasn't written in visual studio so please check the syntax:

  <ListView  Tag="{Binding Path=DataContext,ElementName=theViewName}">
        <ListView.ItemTemplate>
            <DataTemplate>
                <oxy:Plot Tag="{Binding Path=Tag,RelativeSource={RelativeSource AncestorType=ListView}">
                    <oxy:Plot.ContextMenu>
                        <ContextMenu DataContext="{Binding PlacementTarget.Tag, RelativeSource={RelativeSource Self}}">
                            <MenuItem Command="{Binding SavePNG}"/>
                        </ContextMenu>
                    </oxy:Plot.ContextMenu>
                </oxy:Plot>
            </DataTemplate>
        </ListView.ItemTemplate>
    </ListView>