my WPF / Xaml application has a top level menu with File and Edit menuitems. The file menuitem contains Save and Exit menuitems. Only the Save item is bound to an ICommand. The Edit menu is empty.
When I click File the FIRST time to expand the menu, the SaveCommand.CanExecute method is incorrectly called. When I then select Save the method CanExecute is called again (after which Execute is called).
When I click File subsequently the CanExecute is not executed. And when I again click Save, CanExecute and Execute are correctly called.
Clicking Edit or Exit does not trigger CanExecute nor Execute.
How do I prevent the File menuitem calling SaveCommand.CanExecute the first time ? Perhaps my code or the plumbing (binding) are incorrect ?
Below is MainWindow.xaml (MainWindow.xaml.cs contains only the auto-generated code)
<Window x:Class="MyApp.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="clr-namespace:MyApp.ViewModels"
Title="Blah" Height="350" Width="525">
<Window.DataContext>
<local:MyFirstViewModel />
</Window.DataContext>
<Menu>
<MenuItem Header="File" Name="mnItmFile" >
<MenuItem Name="mnItmSave" Header="Save" Command="{Binding Path=SaveCommand}"/>
<MenuItem Header="Exit"/>
</MenuItem>
<MenuItem Header="Edit"/>
</Menu>
</Window>
Below is the ViewModel.
using System;
using System.Windows.Input;
using System.ComponentModel;
namespace MyApp.ViewModels
{
public class MyFirstViewModel : INotifyPropertyChanged
{
public ICommand SaveCommand
{
get { return new MyFirstCommand(); }
}
public event PropertyChangedEventHandler PropertyChanged;
protected virtual void OnPropertyChanged(string propertyName)
{
PropertyChangedEventHandler handler = this.PropertyChanged;
if (handler != null)
{
var e = new PropertyChangedEventArgs(propertyName);
handler(this, e);
}
}
}
}
And here is the command.
using System;
using System.Windows.Input;
namespace MyApp.Commands
{
public class MyFirstCommand : ICommand
{
private static int i = 0; //debug helper
public bool CanExecute(object parameter)
{
i++; //count num of times this method is called
return true;
}
public void Execute(object parameter)
{
//do some stuff
int x = 5;
x++;
}
public event EventHandler CanExecuteChanged;
}
}
I’m using .NET Framework 4 and VS2010.
Nope, this is expected behavior. When you click the “File” Menu, it displays all the child menu items, including the “Save” menu item. The “Save” menu item is calling the
CanExecutemethod after you click the “File” Menu for the first time, because the “Save” menu item is being displayed for the first time.It needs to call the
CanExecutemethod when it’s displayed for the first time, because it will either be greyed-out or not, depending on the result.After that, whenever you click the “File” menu, it doesn’t need to call CanExecute again, because it already knows the result from the first time. It won’t change unless your ICommand raises the
CanExecuteChangedevent.