2

私の 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 を使用しています。

4

2 に答える 2

2

初めて[ファイル]をクリックしてメニューを展開すると、SaveCommand.CanExecuteメソッドが誤って呼び出されます。

いいえ、これは予想される動作です。「ファイル」メニューをクリックすると、「保存」メニュー項目を含むすべての子メニュー項目が表示されます。「保存」メニュー項目が初めて表示されるCanExecuteため、「ファイル」メニューを初めてクリックした後、「保存」メニュー項目がメソッドを呼び出しています。

CanExecute結果に応じてグレー表示されるかどうかに関係なく、初めて表示されるときにメソッドを呼び出す必要があります。

その後、[ファイル]メニューをクリックするたびに、CanExecuteを再度呼び出す必要はありません。これは、最初から結果がわかっているためです。ICommandがCanExecuteChangedイベントを発生させない限り、変更されません。

于 2012-05-31T11:50:55.873 に答える
1

RoutedUICommands を試すことができます:

    <Window x:Class="Combobox.MainWindow"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    Title="MainWindow" Height="350" Width="525"
    xmlns:local="clr-namespace:Combobox">
<Window.DataContext>
    <local:MyFirstViewModel />
</Window.DataContext>
<Window.CommandBindings>
    <CommandBinding Command="Save" CanExecute="CommandBinding_CanExecute" Executed="CommandBinding_Executed"></CommandBinding>
    <CommandBinding Command="Close" CanExecute="CommandBinding_CanExecute_1" Executed="CommandBinding_Executed_1"></CommandBinding>
</Window.CommandBindings>
    <Menu>
    <MenuItem Header="File" Name="mnItmFile" >
        <MenuItem Name="mnItmSave" Header="Save"  Command="Save"/>
        <MenuItem Header="Exit" Command="Close"/>
    </MenuItem>
    <MenuItem Header="Edit"/>
</Menu>

..... プライベート void CommandBinding_CanExecute(オブジェクト送信者、CanExecuteRoutedEventArgs e) { e.CanExecute = true; }

    private void CommandBinding_Executed(object sender, ExecutedRoutedEventArgs e)
    {

    }

    private void CommandBinding_CanExecute_1(object sender, CanExecuteRoutedEventArgs e)
    {
        e.CanExecute = true;
    }

    private void CommandBinding_Executed_1(object sender, ExecutedRoutedEventArgs e)
    {

    }
于 2012-05-31T13:20:08.273 に答える