WPF: MenuItem.CommandParameter绑定设置为null

5

我有一个数据表格,其中定义了以下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为空。
我相当确定绑定可用的命令参数不为空。 这是在.NET 4.0上运行的WPF应用程序。
有人遇到过这种情况吗?

你有多确定,你调试过代码了吗? - trinaldi
我刚刚尝试了您的确切代码,参数已传递...难道您的ICommand实现缺少接收参数的功能吗? - Espen Medbø
@Tico,我分配给CommandParameter的值不是null。此外,如果我修改CommandParameter以便可以在其getter中设置断点,则框架检索的值不为null。 - Klaus Nji
@emedbo, 我之前也在TreeView上使用过这个相同的代码,所以可能是XamDataGrid特有的问题。 - Klaus Nji
尝试通过编程方式创建菜单项,但传递给RelayCommand的CanExecute的命令参数仍为空。非常有趣的问题。 - Klaus Nji
没有意识到我在这里发布了一个类似的问题:http://stackoverflow.com/questions/3696926/wpf-menuitem-style-parameters-not-available-on-menu-first-open - Klaus Nji
1个回答

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>

命令参数现在被正确传递。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接