当前位置: 首页 > 知识库问答 >
问题:

检测从ViewModel WPF中单击的按钮

穆子琪
2023-03-14

我的WPF-App的主窗口上有许多按钮。这些按钮的命令应该具有相同的实现/功能,但根据按下的按钮,函数访问的文件/路径会发生变化。如何在不使用按钮单击事件处理程序(Windows表单)的情况下检测从ViewModel单击了哪个按钮?

下面是类RelayCommand的实现:

public class RelayCommand : ICommand
{

    readonly Func<Boolean> _canExecute;
    readonly Action _execute;


    public RelayCommand(Action execute)
        : this(execute, null)
    {
    }

    public RelayCommand(Action execute, Func<Boolean> canExecute)
    {
        if (execute == null)
            throw new ArgumentNullException("execute");
        _execute = execute;
        _canExecute = canExecute;
    }


    public event EventHandler CanExecuteChanged
    {
        add
        {

            if (_canExecute != null)
                CommandManager.RequerySuggested += value;
        }

        remove
        {

            if (_canExecute != null)
                CommandManager.RequerySuggested -= value;
        }
    }


    public Boolean CanExecute(Object parameter)
    {
        return _canExecute == null ? true : _canExecute();
    }

    public void Execute(Object parameter)
    {
        _execute();
    }
}

以下是ViewModel中命令的代码:

void DoThisWorkExecute()
    {
        // if Button1 is clicked...do this

        // if Button2 is clicked...do this
    }

    bool CanDoThisWorkExecute()
    {
        return true;
    }

    public ICommand ButtonCommand { get { return new RelayCommand(DoThisWorkExecute, CanDoThisWorkExecute); } }

共有1个答案

班安平
2023-03-14

您可以使用< code >命令参数。大概是这样的:

<Button Content="Open" Command="{Binding Path=ButtonCommand}" CommandParameter="Open"/>
<Button Content="Save" Command="{Binding Path=ButtonCommand}" CommandParameter="Save"/>

为此,您需要稍微不同的< code>RelayCommand实现

/// <summary>
/// https://gist.github.com/schuster-rainer/2648922 
/// Implementation from Josh Smith of the RelayCommand
/// </summary>
public class RelayCommand : ICommand
{
    #region Fields

    readonly Predicate<object> _canExecute;
    readonly Action<object> _execute;
    #endregion // Fields

    #region Constructors

    /// <summary>
    /// Initializes a new instance of the <see cref="RelayCommand"/> class.
    /// </summary>
    /// <param name="execute">The execute.</param>
    public RelayCommand(Action<object> execute)
        : this(execute, null)
    {
    }

    /// <summary>
    /// Initializes a new instance of the <see cref="RelayCommand"/> class.
    /// </summary>
    /// <param name="execute">The execute.</param>
    /// <param name="canExecute">The can execute.</param>
    /// <exception cref="System.ArgumentNullException">execute</exception>
    public RelayCommand(Action<object> execute, Predicate<object> canExecute)
    {
        if (execute == null)
            throw new ArgumentNullException("execute");

        _execute = execute;
        _canExecute = canExecute;
    }
    #endregion // Constructors

    #region ICommand Members


    /// <summary>
    /// Occurs when changes occur that affect whether or not the command should execute.
    /// </summary>
    public event EventHandler CanExecuteChanged
    {
        add { CommandManager.RequerySuggested += value; }
        remove { CommandManager.RequerySuggested -= value; }
    }

    /// <summary>
    /// Defines the method that determines whether the command can execute in its current state.
    /// </summary>
    /// <param name="parameter">Data used by the command.  If the command does not require data to be passed, this object can be set to null.</param>
    /// <returns>true if this command can be executed; otherwise, false.</returns>
    public bool CanExecute(object parameter)
    {
        return _canExecute == null ? true : _canExecute(parameter);
    }
    /// <summary>
    /// Defines the method to be called when the command is invoked.
    /// </summary>
    /// <param name="parameter">Data used by the command.  If the command does not require data to be passed, this object can be set to null.</param>
    public void Execute(object parameter)
    {
        _execute(parameter);
    }

    #endregion // ICommand Members
}

但是:我不会询问单击了哪个按钮,而是为每个单独的操作(例如打开、保存、退出)创建一个命令。重用命令(上下文菜单、KeyBdings、工具栏等)时,您将遇到更少的麻烦。您将始终必须提供用户界面元素。这确实打破了MVVM模式。您真的必须摆脱旧的winform方法,才能充分利用RelayCommand的全部功能。

我自己写了一段代码,所以我不必写所有的代码。

<?xml version="1.0" encoding="utf-8" ?>
<CodeSnippets  xmlns="http://schemas.microsoft.com/VisualStudio/2005/CodeSnippet">
    <CodeSnippet Format="1.0.0">
        <Header>
            <Title>RelayCommand</Title>
            <Shortcut>RelayCommand</Shortcut>
            <Description>Code snippet for usage of the Relay Command pattern</Description>
            <Author>Mat</Author>
            <SnippetTypes>
                <SnippetType>Expansion</SnippetType>
            </SnippetTypes>
        </Header>
        <Snippet>
            <Declarations>
                <Literal>
                    <ID>name</ID>
                    <ToolTip>Name of the command</ToolTip>
                    <Default>Save</Default>
                </Literal>
            </Declarations>
            <Code Language="csharp">
                <![CDATA[   private RelayCommand _$name$Command;
        public ICommand $name$Command
        {
            get
            {
                if (_$name$Command == null)
                {
                    _$name$Command = new RelayCommand(param => this.$name$(param),
                        param => this.Can$name$(param));
                }
                return _$name$Command;
            }
        }

        private bool Can$name$(object param)
        {
            return true;
        }

        private void $name$(object param)
        {
            MessageServiceHelper.RegisterMessage(new NotImplementedException());
        }]]>
            </Code>
        </Snippet>
    </CodeSnippet>
</CodeSnippets>

另见https://msdn.microsoft.com/en-us/library/z41h7fat.aspx

 类似资料:
  • 问题内容: 我对javascript不太熟悉,但是我认为这是实现我的目标的最佳方法。如果没有,请纠正我。 我最后有一个许可证文本2按钮。所有这些都是用HTML编写的,因为许可证中有一些链接。现在,我希望当用户单击中的“确定”按钮时,这会触发一些我可以在Java中抓取的JavaScript或侦听器以触发应用程序中的前进。(“取消”按钮的作用相反,但是如果我知道一种方法,我可以做另一种。) 这会给某人

  • 我有:我在水平滚动视图中有一组按钮 我想要的:我想要在双击按钮时检测事件 注意通常我处理点击事件使用.但是现在我怎么能实现同样的双击。如果有任何界面我也可以用于此目的,这将是有帮助的

  • 问题内容: 我正在使用Scrapy爬行网页。单击某些按钮时,仅会弹出一些我需要的信息(当然,单击后也会显示在HTML代码中)。 我发现Scrapy可以处理的形式(如登录)如图所示这里。但是问题在于没有表格可以填写,所以这不是我所需要的。 如何简单地单击一个按钮,然后显示我需要的信息? 我是否必须使用诸如机械化或lxml之类的外部库? 问题答案: Scrapy无法解释javascript。 如果你绝

  • 我正在尝试在Selenium中测试图像按钮点击。 图像是事件,当我点击sgt消息出现我 超文本标记语言代码:

  • 在我的应用程序中,我有一个按钮。单击和双击按钮后,将执行单独的操作。我该怎么做?谢谢

  • 我正在制作一个棋盘游戏,8X8矩阵,在一个框架中有64个。到目前为止,我的代码是这样的: 我试图告诉哪个JButoon是使用此代码单击的: 然而,我不知道如何辨别点击了哪个Jbutton。