C# 如何将WPF按钮绑定到ViewModelBase中的命令?

C# 如何将WPF按钮绑定到ViewModelBase中的命令?,c#,wpf,mvvm,command,viewmodel,C#,Wpf,Mvvm,Command,Viewmodel,我有一个包含各种属性的视图AttributeView。还有一个按钮,当按下时,它应该设置属性的默认值。我还有一个ViewModelBase类,它是我所有ViewModels的基类。 问题是我似乎无法使用WPF将按钮绑定到命令 我已经试过了,但是没有任何效果: <Button Command="{Binding DataInitialization}" Content="{x:Static localProperties:Resources.BtnReinitializeData}">

我有一个包含各种属性的视图
AttributeView
。还有一个按钮,当按下时,它应该设置属性的默认值。我还有一个
ViewModelBase
类,它是我所有ViewModels的基类。 问题是我似乎无法使用WPF将按钮绑定到命令

我已经试过了,但是没有任何效果:

<Button Command="{Binding DataInitialization}" Content="{x:Static localProperties:Resources.BtnReinitializeData}"></Button>
在应用程序启动时,将为该命令创建一个新实例:

DataInitialization = new DataInitializationCommand()
但是,WPF绑定似乎没有“找到”命令(按下按钮不起任何作用)。当前视图中使用的ViewModel来自
ViewModelBase
。我还可以尝试什么(我对WPF很陌生,所以这可能是一个非常简单的问题)

ViewModel:

public class ViewModelBase
{
    private ICommand _clickCommand;
    public ICommand ClickCommand
    {
        get
        {
            return _clickCommand ?? (_clickCommand = new CommandHandler(() => MyAction(), ()=> CanExecute));
        }
    }
     public bool CanExecute
     {
        get
        {
            // check if executing is allowed, i.e., validate, check if a process is running, etc. 
            return true/false;
        }
     }

    public void MyAction()
    {

    }
}
命令处理程序:

 public class CommandHandler : ICommand
{
    private Action _action;
    private Func<bool> _canExecute;

    /// <summary>
    /// Creates instance of the command handler
    /// </summary>
    /// <param name="action">Action to be executed by the command</param>
    /// <param name="canExecute">A bolean property to containing current permissions to execute the command</param>
    public CommandHandler(Action action, Func<bool> canExecute)
    {
        _action = action;
        _canExecute = canExecute;
    }

    /// <summary>
    /// Wires CanExecuteChanged event 
    /// </summary>
    public event EventHandler CanExecuteChanged
    {
        add { CommandManager.RequerySuggested += value; }
        remove { CommandManager.RequerySuggested -= value; }
    }

    /// <summary>
    /// Forcess checking if execute is allowed
    /// </summary>
    /// <param name="parameter"></param>
    /// <returns></returns>
    public bool CanExecute(object parameter)
    {
        return _canExecute.Invoke();
    }

    public void Execute(object parameter)
    {
        _action();
    }
}
公共类CommandHandler:ICommand
{
私人行动;
私人职能执行;
/// 
///创建命令处理程序的实例
/// 
///要由命令执行的操作
///包含执行命令的当前权限的bolean属性
公共命令处理程序(操作,Func canExecute)
{
_行动=行动;
_canExecute=canExecute;
}
/// 
///导线可以执行更改事件
/// 
公共事件事件处理程序CanExecuteChanged
{
添加{CommandManager.RequerySuggested+=value;}
删除{CommandManager.RequerySuggested-=value;}
}
/// 
///强制检查是否允许执行
/// 
/// 
/// 
公共布尔CanExecute(对象参数)
{
return _canExecute.Invoke();
}
public void Execute(对象参数)
{
_动作();
}
}

我希望这会给你一个想法。

CommandBase是否继承了ICommand?按钮DataContext是否包含DataInitialization命令?输出面板中是否有关于绑定的消息?是的,它继承ICommand。如何检查按钮的DataContext?我不确定输出中是否有消息(默认情况下是否有消息?)。如果您显示更多关于viewmodel和XAML的代码,会更容易。您可以显示实现ICommand接口成员的VM代码吗?您是指DataInitializationCommand代码吗(它源于CommandBase,CommandBase反过来又实现了ICommand)?VM与ICommand接口的关系如何?这给了我一个搜索的线索。结果表明,该命令在多个位置初始化,其中一个位置(正确的位置)被注释掉:)谢谢!是的,经过多次查找,这是我找到的最好的解释。感谢@ethicalogics看起来您忘记初始化_clickCommand,因此您的示例将始终在访问clickCommand属性时创建新的CommandHandler对象。
CanExecute
的目的是让您在评估时确定该命令是否可执行。如果计算结果为false,则通常禁用该控件。只需将其设置为true是常见的,也完全可以。此外,要使用_canExecute,您必须实现关于此的通知。WPF有内置的默认机制来重新查询CanExecute属性。但要执行此操作,您的ICommand必须重新订阅默认命令管理器,如下所示:`public EventHandler CanExecuteChanged{add{CommandManager.RequerySuggested+=value;}remove{CommandManager.RequerySuggested-=value;}`
public partial class MainWindow : Window
{
    public MainWindow()
    {
        InitializeComponent();
        DataContext = new ViewModelBase();
    }
}
public class ViewModelBase
{
    private ICommand _clickCommand;
    public ICommand ClickCommand
    {
        get
        {
            return _clickCommand ?? (_clickCommand = new CommandHandler(() => MyAction(), ()=> CanExecute));
        }
    }
     public bool CanExecute
     {
        get
        {
            // check if executing is allowed, i.e., validate, check if a process is running, etc. 
            return true/false;
        }
     }

    public void MyAction()
    {

    }
}
 public class CommandHandler : ICommand
{
    private Action _action;
    private Func<bool> _canExecute;

    /// <summary>
    /// Creates instance of the command handler
    /// </summary>
    /// <param name="action">Action to be executed by the command</param>
    /// <param name="canExecute">A bolean property to containing current permissions to execute the command</param>
    public CommandHandler(Action action, Func<bool> canExecute)
    {
        _action = action;
        _canExecute = canExecute;
    }

    /// <summary>
    /// Wires CanExecuteChanged event 
    /// </summary>
    public event EventHandler CanExecuteChanged
    {
        add { CommandManager.RequerySuggested += value; }
        remove { CommandManager.RequerySuggested -= value; }
    }

    /// <summary>
    /// Forcess checking if execute is allowed
    /// </summary>
    /// <param name="parameter"></param>
    /// <returns></returns>
    public bool CanExecute(object parameter)
    {
        return _canExecute.Invoke();
    }

    public void Execute(object parameter)
    {
        _action();
    }
}