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

Posted

技术标签:

【中文标题】如何将 WPF 按钮绑定到 ViewModelBase 中的命令?【英文标题】:How to bind WPF button to a command in ViewModelBase? 【发布时间】:2012-09-07 12:37:07 【问题描述】:

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

我试过这个,但它什么也没做:

<Button Command="Binding DataInitialization" Content="x:Static localProperties:Resources.BtnReinitializeData"></Button>

命令是这样定义的(在ViewModelBase中):

public CommandBase DataInitialization  get; protected set; 

并在应用程序启动时为命令创建一个新实例:

DataInitialization = new DataInitializationCommand()

然而,WPF 绑定似乎并没有“找到”命令(按下按钮什么都不做)。当前视图中使用的 ViewModel 派生自ViewModelBase。我还能尝试什么(我对 WPF 很陌生,所以这可能是一个非常简单的问题)?

【问题讨论】:

CommandBase 是否继承自 ICommand? Buttons DataContext 是否包含 DataInitialization 命令?您在输出面板中是否有任何关于绑定的消息? 是的,它继承了 ICommand。如何检查按钮的 DataContext?我不确定输出中的消息(默认情况下应该有吗?)。 如果您显示更多关于视图模型和 xaml 的代码会更容易 你能否展示一下你的VM代码,ICommand接口的成员是在哪里实现的。 您的意思是DataInitializationCommand 代码(它源自CommandBase,后者又实现了ICommand)? VM 与 ICommand 接口有何关系? 【参考方案1】:
 <Grid >
    <Grid.ColumnDefinitions>
        <ColumnDefinition Width="*"/>
    </Grid.ColumnDefinitions>
    <Button Command="Binding ClickCommand" Width="100" Height="100" Content="wefwfwef"/>
</Grid>

窗口背后的代码:

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();
    

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

【讨论】:

这给了我在哪里搜索的线索。事实证明,该命令在多个地方进行了初始化,其中一个地方(正确的地方)被注释掉了 :) 谢谢! 是的,这是我在多次查找后找到的最佳解释。谢谢@Ethicallogics 看起来您忘记初始化 _clickCommand,因此您的示例将始终在访问 ClickCommand 属性时创建新的 CommandHandler 对象... CanExecute 的目的是让您在评估时决定该命令是否可执行。如果它评估为 false,则该控件通常被禁用。只需将其设置为 true 就很常见而且完全没问题。 此外,要使用 _canExecute,您必须实现有关此的通知。并且 WPF 具有重新查询 CanExecute 属性的内置默认机制。但要做到这一点,您的 ICommand 必须重新订阅默认命令管理器,如下所示:` public event EventHandler CanExecuteChanged add CommandManager.RequerySuggested += value; 删除 CommandManager.RequerySuggested -= 值; `

以上是关于如何将 WPF 按钮绑定到 ViewModelBase 中的命令?的主要内容,如果未能解决你的问题,请参考以下文章

WPF:如何使用 MVVM 将命令绑定到 ListBoxItem?

如何将WPF中的命令绑定到控件的双击事件处理程序

如何将 DataGrid 中的文本框绑定到 Wpf 中的列表?

将 WPF 按钮 CommandParameter 绑定到 DataTemplate 中的按钮本身

WPF如何将mousedown(命令/动作)绑定到标签

wpf usercontrol,将按钮的命令参数绑定到父用户控件