我希望能够将两个不同的Command
分配给Button
:
Click
活动Command
Hold
event使用HoldTimeout
属性指定保留持续时间的命令
public static readonly DependencyProperty HoldCommandProperty =
DependencyProperty.Register(
"HoldCommand",
typeof(ICommand),
typeof(CommandButton),
new PropertyMetadata(null,
CommandChanged));
public ICommand HoldCommand
{
get { return (ICommand)GetValue(CommandProperty); }
set { SetValue(CommandProperty, value); }
}
如何计算点击次数和时间保持并在何处进行计算?如果使用按钮的“命令”属性,我不确定处理Click事件是否正确。
结果XAML看起来应该是这样的:
<CommandButton x:Name="InputButton"
Command="{Binding PrimaryCommand}"
CommandParameter="{Binding}"
HoldCommand="{Binding SecondaryCommand}"
HoldCommandParameters="{Binding}"
HoldTimeout="2000"/>
我已经阅读了如何实现双击,但这不完全是:
答案 0 :(得分:5)
您需要创建自定义控件并使用DispatcherTimer类对其进行计时。您可以添加另一个布尔值和命令属性来激活此行为。
控制如下:
public class SmartButton : Button
{
private DispatcherTimer _timer;
public int MillisecondsToWait
{
get { return (int)GetValue(MillisecondsToWaitProperty); }
set { SetValue(MillisecondsToWaitProperty, value); }
}
public DispatcherTimer Timer
{
get { return _timer; }
set { _timer = value; }
}
public ICommand ClickAndHoldCommand
{
get { return (ICommand)GetValue(ClickAndHoldCommandProperty); }
set { SetValue(ClickAndHoldCommandProperty, value); }
}
public bool EnableClickHold
{
get { return (bool)GetValue(EnableClickHoldProperty); }
set { SetValue(EnableClickHoldProperty, value); }
}
// Using a DependencyProperty as the backing store for EnableClickHold. This enables animation, styling, binding, etc...
public static readonly DependencyProperty EnableClickHoldProperty =
DependencyProperty.Register("EnableClickHold", typeof(bool), typeof(SmartButton), new PropertyMetadata(false));
// Using a DependencyProperty as the backing store for ClickAndHoldCommand. This enables animation, styling, binding, etc...
public static readonly DependencyProperty ClickAndHoldCommandProperty =
DependencyProperty.Register("ClickAndHoldCommand", typeof(ICommand), typeof(SmartButton), new UIPropertyMetadata(null));
// Using a DependencyProperty as the backing store for MillisecondsToWait. This enables animation, styling, binding, etc...
public static readonly DependencyProperty MillisecondsToWaitProperty =
DependencyProperty.Register("MillisecondsToWait", typeof(int), typeof(SmartButton), new PropertyMetadata(0));
public SmartButton()
{
this.PreviewMouseLeftButtonUp += OnPreviewMouseLeftButtonUp;
this.PreviewMouseLeftButtonDown += OnPreviewMouseLeftButtonDown;
}
private void OnPreviewMouseLeftButtonUp(object sender, MouseButtonEventArgs e)
{
if (EnableClickHold)
{
bool isMouseReleaseBeforeHoldTimeout = Timer.IsEnabled;
ResetAndRemoveTimer();
// Consider it as a mouse click
if (isMouseReleaseBeforeHoldTimeout && Command != null)
{
Command.Execute(CommandParameter);
}
e.Handled = true;
}
}
private void OnPreviewMouseLeftButtonDown(object sender, MouseButtonEventArgs e)
{
if (EnableClickHold)
{
Timer = new DispatcherTimer(DispatcherPriority.Normal, this.Dispatcher)
{
Interval = TimeSpan.FromMilliseconds(MillisecondsToWait)
};
Timer.Tick += Timer_Tick;
Timer.IsEnabled = true;
Timer.Start();
e.Handled = true;
}
}
void Timer_Tick(object sender, EventArgs e)
{
if(ClickAndHoldCommand != null)
{
this.ClickAndHoldCommand.Execute(this.CommandParameter);
}
ResetAndRemoveTimer();
}
private void ResetAndRemoveTimer()
{
if (Timer == null) return;
Timer.Tick -= Timer_Tick;
Timer.IsEnabled = false;
Timer.Stop();
Timer = null;
}
}
这个xaml看起来应该是
<wpfMouseClick:SmartButton x:Name="MySmartButton"
Width="100"
Height="50"
ClickAndHoldCommand="{Binding Path=MyTestCommand,
ElementName=MyWindow}"
EnableClickHold="True"
MillisecondsToWait="1000">
Click and Hold
</wpfMouseClick:SmartButton>
答案 1 :(得分:3)
查看RepeatButton控件,该控件从您单击它到释放时重复触发Click
事件。
要对此进行扩展,您可以控制触发的Click
个事件的间隔,并跟踪在给定时间内将执行的事件数。例如,如果Interval
属性设置为 1000 ,则会每秒触发Click
个事件。跟踪计数器发射的数量;一旦 5 触发,这意味着用户按住按钮五秒钟,您可以将“Click&amp; Hold”事件逻辑放在RepeatButton
Click
事件处理程序中然后重置计数器。
答案 2 :(得分:1)
如何使用EventTriggers和StopWatch。
<UserControl xmlns:i="http://schemas.microsoft.com/expression/2010/interactivity">
<Button>
<i:Interaction.Triggers>
<i:EventTrigger EventName="PreviewMouseDown">
<i:InvokeCommandAction Command="{Binding DownCmd}" />
</i:EventTrigger>
<i:EventTrigger EventName="PreviewMouseUp">
<i:InvokeCommandAction Command="{Binding UpCmd}" />
</i:EventTrigger>
</i:Interaction.Triggers>
</Button>
</UserControl>
这是C#。我在ViewModel中使用代码。
Stopwatch _buttonHoldStopWatch;
public DelegateCommand DownCmd { get; set; }
public DelegateCommand UpCmd { get; set; }
// Delegate commands are from the Prism framework but you can switch these out to
regular ICommands
ResetValueDownCmd = new DelegateCommand(Down);
ResetValueUpCmd = new DelegateCommand(Up);
// User pressed down
private void Down(object dayObject)
{
_buttonHoldStopWatch.Start(); // start watch
}
// User left go of press
private void Up(object dayObject)
{
// Did the user hold down the button for 0.5 sec
if (_buttonHoldStopWatch.ElapsedMilliseconds >= 500)
{
// Do something
}
_buttonHoldStopWatch.Stop(); // stop watch
_buttonHoldStopWatch.Reset(); // reset elapsed time
}