私の WPF / Xaml アプリケーションには、ファイルと編集のメニュー項目を含む最上位のメニューがあります。ファイル menuitem には、Save および Exit メニュー項目が含まれています。Save アイテムのみが ICommand にバインドされます。編集メニューは空です。
[ファイル] を最初にクリックしてメニューを展開すると、SaveCommand.CanExecute メソッドが間違って呼び出されます。次に [保存] を選択すると、CanExecute メソッドが再度呼び出されます (その後、Execute が呼び出されます)。
続いて [ファイル] をクリックすると、CanExecute が実行されません。そして、もう一度 [保存] をクリックすると、CanExecute と Execute が正しく呼び出されます。
[編集] または [終了] をクリックしても、CanExecute も Execute もトリガーされません。
File menuitem が初めて SaveCommand.CanExecute を呼び出すのを防ぐにはどうすればよいですか? おそらく私のコードまたは配管 (バインディング) が間違っていますか?
以下は MainWindow.xaml です (MainWindow.xaml.cs には自動生成されたコードのみが含まれています)
<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>
以下は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);
}
}
}
}
そして、ここにコマンドがあります。
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;
}
}
.NET Framework 4 と VS2010 を使用しています。