WPF:MenuItem.CommandParameter绑定设置为null

时间:2013-12-18 23:46:26

标签: c# wpf mvvm binding menuitem

我为我的数据网格定义了以下ContextMenu:

<igDP:XamDataGrid.ContextMenu>
    <ContextMenu ItemsSource="{Binding CommandViewModels}"                     >
        <ContextMenu.ItemContainerStyle>
            <Style TargetType="MenuItem">
                <Setter Property="Command" Value="{Binding Command}" />
                <Setter Property="CommandParameter" Value="{Binding CommandParameter}" />
                <Setter Property="Header" Value="{Binding Name}" />
                <Setter Property="Icon" Value="{Binding Icon}" />
            </Style>
        </ContextMenu.ItemContainerStyle>
    </ContextMenu>
</igDP:XamDataGrid.ContextMenu>

CommandViewModel类定义如下:

public class CommandViewModel : ICommandViewModel
    {
        public CommandViewModel(string name, Image icon, ICommand command, object commandParameter = null, int index = 0)
        {
            Name = name;
            Icon = icon;
            Command = command;
            CommandParameter = commandParameter;
            Index = index;
        }

        public string Name { get; set; }
        public Image Icon { get; set; }
        public ICommand Command { get; set; }
        public object CommandParameter { get; set; }
        public int Index { get; set; }     
    }

当我右键单击网格中的一行时,ContextMenu的每个MenuItem都被正确设置样式。 MenuItem的图标,标签和命令与预期一致。但是,作为参数传递给绑定到MenuItem.Command的RelayCommand的命令参数CommandViewModel.CommandParameter为null。

我相当确定绑定可用的命令参数不为null。这是在.NET 4.0上运行的WPF应用程序。

有人经历过这个吗?

1 个答案:

答案 0 :(得分:2)

这显然是CommandParameter绑定的一个已知问题。

由于我不想编辑Prism代码,我最终使用了引用的CodePlex帖子中定义的CommandParameterBehavior类。

修改我的自定义RelayCommand类以实现IDelegateCommand,如下所示:

 public class RelayCommand : IDelegateCommand
{
    readonly protected Predicate<object> _canExecute;
    readonly protected Action<object> _execute;      

    public RelayCommand(Predicate<object> canExecute, Action<object> execute)
    {
        _canExecute = canExecute;
        _execute = execute;          
    }

    public void RaiseCanExecuteChanged()
    {
        if (CanExecuteChanged != null)
            CanExecuteChanged(this, EventArgs.Empty);
    }      

    public virtual bool CanExecute(object parameter)
    {
        return _canExecute(parameter);
    }

    public event EventHandler CanExecuteChanged;

    public virtual void Execute(object parameter)
    {
        _execute(parameter);
    }      
}

并修改我的原始样式以使用CommandParameterBehavior,如下所示:

 <Style TargetType="MenuItem">
                <Setter Property="Command" Value="{Binding Command}" />
                <Setter Property="CommandParameter" Value="{Binding CommandParameter}" />
                <Setter Property="Header" Value="{Binding Name}" />
                <Setter Property="Icon" Value="{Binding Icon}" />
                <Setter Property="utility:CommandParameterBehavior.IsCommandRequeriedOnChange" Value="true"
            </Style>

CommandParameter现在正确传递。