WPF - CanExecute doesn't work for DataGrid's ContextMenu

白昼怎懂夜的黑 提交于 2019-12-11 01:44:40

问题


I wanted to have my DataGrids with a context menu that allows the user to move the selected rows up or down. After some search, I've come up with the following code that has a problem. It seems that CanExecute is only called once (I guess when the menu gets created), so my MenuItem will either be enabled or disabled all of the time. What I am struggling to achieve is to make it enabled when there are rows selected in the DataGrid and disabled when there aren't any. Currently this doesn't work.

Also, is there a more elegant solution to this? If I use more code I think it will become a huge mess...

public class DataGridMoveRowsUpCommand : ICommand
{
    public event EventHandler CanExecuteChanged;

    public bool CanExecute(object parameter)
    {
        var grid = parameter as DataGrid;
        if (grid != null && grid.SelectedItems.Count > 0) return true;
        return false;
    }

    public void Execute(object parameter)
    {
        // Do sth...
    }

    public void RaiseCanExecuteChanged()
    {
        if (CanExecuteChanged != null) CanExecuteChanged(this, EventArgs.Empty);
    }
}
//-------------------------------------------------------------
public class MyDataGrid : DataGrid
{
    public static ICommand DataGridMoveRowsUp
    {
        get { return new DataGridMoveRowsUpCommand(); }
    }
}
//-------------------------------------------------------------
        <kbm:MyDataGrid x:Name="gridExpenses" ContextMenu="{StaticResource DataGridContextMenu}"/>

//-------------------------------------------------------------
        <ContextMenu x:Key="DataGridContextMenu" x:Shared="true">
            <MenuItem Header="{DynamicResource StringMoveUp}"
                     Command="kbm:MyDataGrid.DataGridMoveRowsUp"
                     CommandTarget="{Binding Path=PlacementTarget, RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type ContextMenu}}}"
                     CommandParameter="{Binding Path=PlacementTarget, RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type ContextMenu}}}">
            </MenuItem>
        ...

回答1:


You have to manually called RaiseCanExecuteChanged method whenever you feel like that command needs to be revaluated. (Most probably in case SelectedItems of dataGrid gets changed.)

OR

Either you can let CommandManager decides when to raise CanExecuteChanged event of your command by hooking onto RequerySuggested event of CommandManager like this:

public event EventHandler CanExecuteChanged
{
    add { CommandManager.RequerySuggested += value; }
    remove { CommandManager.RequerySuggested -= value; }
}

RequerySuggested event Occurs when the System.Windows.Input.CommandManager detects conditions that might change the ability of a command to execute.



来源:https://stackoverflow.com/questions/21585518/wpf-canexecute-doesnt-work-for-datagrids-contextmenu

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!