我的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); } }
您可以使用< 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
}
但是:我不会询问单击了哪个按钮,而是为每个单独的操作(例如打开、保存、退出)创建一个命令。重用命令(上下文菜单、KeyBding
s、工具栏等)时,您将遇到更少的麻烦。您将始终必须提供用户界面元素。这确实打破了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。