I'm new to WPF. Currently, I want to allow my Add button to add item by using either single click or double click. However, when I try to double click, it ends up fire single click event twice. Code in XAML as below:
我新的WPF。目前,我希望允许我的Add按钮通过单击或双击添加项。然而,当我尝试双击时,它会触发两次单击事件。XAML中的代码如下:
<Button.InputBindings>
<MouseBinding Command="{Binding Path=AddCommand}" CommandParameter="{Binding}" MouseAction="LeftClick" />
<MouseBinding Command="{Binding Path=AddCommand}" CommandParameter="{Binding}" MouseAction="LeftDoubleClick" />
I found solution online which is to use DispatcherTimer in order to solve the problem. I have inserted these in code behind:
我在网上找到了解决方案,就是使用DispatcherTimer来解决这个问题。我在后面的代码中插入了这些:
private static DispatcherTimer myClickWaitTimer =
new DispatcherTimer(
new TimeSpan(0, 0, 0, 1),
DispatcherPriority.Background,
mouseWaitTimer_Tick,
Dispatcher.CurrentDispatcher);
private void btnAdd_MouseDoubleClick(object sender, MouseButtonEventArgs e)
{
// Stop the timer from ticking.
myClickWaitTimer.Stop();
// Handle Double Click Actions
}
private void btnAdd_Click(object sender, RoutedEventArgs e)
{
myClickWaitTimer.Start();
}
private static void mouseWaitTimer_Tick(object sender, EventArgs e)
{
myClickWaitTimer.Stop();
// Handle Single Click Actions
}
So here comes my question. I've removed the MouseBinding in XAML and want to call for AddCommand in code behind but I'm having problem to do so due to the PrismEventAggregator. The AddCommand in .cs as below:
我的问题来了。我已经删除了XAML中的MouseBinding,并想在后面调用AddCommand代码,但是由于使用的是calculmeventaggregator,所以我无法这样做。AddCommand in .cs如下:
private void AddCommandExecute(Object commandArg)
{
// Broadcast Prism event for adding item
this.PrismEventAggregator.GetEvent<AddItemEvent>().Publish(
new AddItemPayload()
{
BlockType = this.BlockType
}
);
}
Hence would like to know how to call for the AddCommand (which is a Prism Event in .cs) in Code behind?
因此,我们想知道如何在后面的代码中调用AddCommand(在.cs中是一个Prism事件)?
Note: The button is inside resource dictionary thus I failed to use the button name to call for the command.
注意:按钮在资源字典中,因此我没有使用按钮名来调用命令。
2 个解决方案
#1
0
You need to create a class which will subscribe to the event you are publishing and then execute the logic you want.
您需要创建一个类来订阅要发布的事件,然后执行所需的逻辑。
For example:
例如:
public class AddItemViewModel : INotifyPropertyChanged
{
private IEventAggregator _eventAggregator;
public AddItemViewModel(IEventAggregator eventAggregator)
{
_eventAggregator = eventAggregator;
_eventAggregator.GetEvent<AddItemEvent>().Subscribe(AddItem);
}
private void AddItem(AddItemPayload payload)
{
// Your logic here
}
}
Then when you publish the event it will trigger the subscriber and execute.
然后,当您发布事件时,它将触发订阅服务器并执行。
#2
0
Using Expression Blend SDK, you can create a Behavior
that encapsulates all your custom logic. This behavior will offer two dependency properties for your command and its parameter, so you can easily create Binding
s for them, exactly as you do this for your InputBinding
s.
使用Expression Blend SDK,您可以创建一个行为来封装所有自定义逻辑。此行为将为您的命令及其参数提供两个依赖项属性,因此您可以轻松地为它们创建绑定,就像您为InputBindings提供绑定一样。
Move your event handlers and DispatcherTimer
logic into this behavior:
将事件处理程序和DispatcherTimer逻辑移动到以下行为中:
using System.Windows.Interactivity;
class ClickBehavior : Behavior<Button>
{
// a dependency property for the command
public static readonly DependencyProperty CommandProperty =
DependencyProperty.Register("Command", typeof(ICommand),
typeof(ClickBehavior), new PropertyMetadata(null));
// a dependency property for the command's parameter
public static readonly DependencyProperty CommandParameterProperty =
DependencyProperty.Register("CommandParameter", typeof(object),
typeof(ClickBehavior), new PropertyMetadata(null));
public ICommand Command
{
get { return (ICommand)this.GetValue(CommandProperty); }
set { this.SetValue(CommandProperty, value); }
}
public object CommandParameter
{
get { return this.GetValue(CommandParameterProperty); }
set { this.SetValue(CommandParameterProperty, value); }
}
// on attaching to a button, subscribe to its Click and MouseDoubleClick events
protected override void OnAttached()
{
this.AssociatedObject.Click += this.AssociatedObject_Click;
this.AssociatedObject.MouseDoubleClick += this.AssociatedObject_MouseDoubleClick;
}
// on detaching, unsubscribe to prevent memory leaks
protected override void OnDetaching()
{
this.AssociatedObject.Click -= this.AssociatedObject_Click;
this.AssociatedObject.MouseDoubleClick -= this.AssociatedObject_MouseDoubleClick;
}
// move your event handlers here
private void AssociatedObject_Click(object sender, RoutedEventArgs e)
{ //... }
private void AssociatedObject_MouseDoubleClick(object sender, MouseButtonEventArgs e)
{ //... }
// call this method in your event handlers to execute the command
private void ExecuteCommand()
{
if (this.Command != null && this.Command.CanExecute(this.CommandParameter))
{
this.Command.Execute(this.CommandParameter);
}
}
The usage is very simple. You need to declare your additional namespaces:
用法很简单。您需要声明附加的名称空间:
<Window
xmlns:local="Your.Behavior.Namespace"
xmlns:i="http://schemas.microsoft.com/expression/2010/interactivity"
...
Finally, attach the behavior to the button:
最后,将行为附加到按钮上:
<Button>
<i:Interaction.Behaviors>
<local:ClickBehavior Command="{Binding AddCommand}" CommandParameter="{Binding}"/>
</i:Interaction.Behaviors>
</Button>
#1
0
You need to create a class which will subscribe to the event you are publishing and then execute the logic you want.
您需要创建一个类来订阅要发布的事件,然后执行所需的逻辑。
For example:
例如:
public class AddItemViewModel : INotifyPropertyChanged
{
private IEventAggregator _eventAggregator;
public AddItemViewModel(IEventAggregator eventAggregator)
{
_eventAggregator = eventAggregator;
_eventAggregator.GetEvent<AddItemEvent>().Subscribe(AddItem);
}
private void AddItem(AddItemPayload payload)
{
// Your logic here
}
}
Then when you publish the event it will trigger the subscriber and execute.
然后,当您发布事件时,它将触发订阅服务器并执行。
#2
0
Using Expression Blend SDK, you can create a Behavior
that encapsulates all your custom logic. This behavior will offer two dependency properties for your command and its parameter, so you can easily create Binding
s for them, exactly as you do this for your InputBinding
s.
使用Expression Blend SDK,您可以创建一个行为来封装所有自定义逻辑。此行为将为您的命令及其参数提供两个依赖项属性,因此您可以轻松地为它们创建绑定,就像您为InputBindings提供绑定一样。
Move your event handlers and DispatcherTimer
logic into this behavior:
将事件处理程序和DispatcherTimer逻辑移动到以下行为中:
using System.Windows.Interactivity;
class ClickBehavior : Behavior<Button>
{
// a dependency property for the command
public static readonly DependencyProperty CommandProperty =
DependencyProperty.Register("Command", typeof(ICommand),
typeof(ClickBehavior), new PropertyMetadata(null));
// a dependency property for the command's parameter
public static readonly DependencyProperty CommandParameterProperty =
DependencyProperty.Register("CommandParameter", typeof(object),
typeof(ClickBehavior), new PropertyMetadata(null));
public ICommand Command
{
get { return (ICommand)this.GetValue(CommandProperty); }
set { this.SetValue(CommandProperty, value); }
}
public object CommandParameter
{
get { return this.GetValue(CommandParameterProperty); }
set { this.SetValue(CommandParameterProperty, value); }
}
// on attaching to a button, subscribe to its Click and MouseDoubleClick events
protected override void OnAttached()
{
this.AssociatedObject.Click += this.AssociatedObject_Click;
this.AssociatedObject.MouseDoubleClick += this.AssociatedObject_MouseDoubleClick;
}
// on detaching, unsubscribe to prevent memory leaks
protected override void OnDetaching()
{
this.AssociatedObject.Click -= this.AssociatedObject_Click;
this.AssociatedObject.MouseDoubleClick -= this.AssociatedObject_MouseDoubleClick;
}
// move your event handlers here
private void AssociatedObject_Click(object sender, RoutedEventArgs e)
{ //... }
private void AssociatedObject_MouseDoubleClick(object sender, MouseButtonEventArgs e)
{ //... }
// call this method in your event handlers to execute the command
private void ExecuteCommand()
{
if (this.Command != null && this.Command.CanExecute(this.CommandParameter))
{
this.Command.Execute(this.CommandParameter);
}
}
The usage is very simple. You need to declare your additional namespaces:
用法很简单。您需要声明附加的名称空间:
<Window
xmlns:local="Your.Behavior.Namespace"
xmlns:i="http://schemas.microsoft.com/expression/2010/interactivity"
...
Finally, attach the behavior to the button:
最后,将行为附加到按钮上:
<Button>
<i:Interaction.Behaviors>
<local:ClickBehavior Command="{Binding AddCommand}" CommandParameter="{Binding}"/>
</i:Interaction.Behaviors>
</Button>