2

我的 WPF / Xaml 应用程序有一个带有文件和编辑菜单项的顶级菜单。文件菜单项包含保存和退出菜单项。只有 Save 项绑定到 ICommand。编辑菜单为空。

当我第一次单击 File 以展开菜单时,SaveCommand.CanExecute 方法被错误地调用。然后,当我选择保存时,再次调用 CanExecute 方法(之后调用 Execute)。

当我随后单击文件时,CanExecute 没有执行。当我再次单击保存时,CanExecute 和 Execute 被正确调用。

单击 Edit 或 Exit 不会触发 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>

下面是视图模型。

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

当我第一次单击 File 以展开菜单时,SaveCommand.CanExecute 方法被错误地调用。

不,这是预期的行为。单击“文件”菜单时,会显示所有子菜单项,包括“保存”菜单项。第一次单击“文件”菜单后,“保存”菜单项调用该CanExecute方法,因为第一次显示“保存”菜单项。

它需要CanExecute在第一次显示时调用该方法,因为它是否会变灰,具体取决于结果。

之后,每当你点击“文件”菜单时,它就不需要再次调用 CanExecute,因为它从第一次就已经知道结果了。CanExecuteChanged除非您的 ICommand 引发事件,否则它不会改变。

于 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>

.....私有无效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 回答