C# MVVM:按钮保持事件命令
我希望能够将两个不同的C# MVVM:按钮保持事件命令,c#,wpf,mvvm,C#,Wpf,Mvvm,我希望能够将两个不同的命令分配给按钮: 单击事件命令 Hold事件命令,该命令使用HoldTimeout属性指定保持持续时间 public static readonly DependencyProperty HoldCommandProperty = DependencyProperty.Register( "HoldCommand", typeof(ICommand), typeof(CommandButton), new P
命令
分配给按钮
:
事件单击
命令
事件命令,该命令使用Hold
属性指定保持持续时间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); } }
<CommandButton x:Name="InputButton"
Command="{Binding PrimaryCommand}"
CommandParameter="{Binding}"
HoldCommand="{Binding SecondaryCommand}"
HoldCommandParameters="{Binding}"
HoldTimeout="2000"/>
我已经阅读了如何实现双击,但这并不完全是:
单击事件
要对此进行扩展,您可以控制触发的单击
事件的间隔,并跟踪在给定时间内将执行多少事件。例如,如果Interval
属性设置为1000,它将每秒触发单击事件。跟踪使用计数器射击的数量;一旦5触发,这意味着用户按住按钮5秒钟,您可以将“单击并按住”事件逻辑放入RepeatButton
单击事件处理程序,然后重置计数器。您需要创建一个自定义控件并使用Dispatcher类对其计时。可以添加另一个布尔值和命令属性来激活此行为
控制措施如下:
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>
点击并按住
使用事件触发器和秒表怎么样
<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>
好主意。我想知道如果HoldTimeout设置为2500毫秒,如何获得点击计数参考?谢谢你的完整解决方案。一件小事是,我需要能够使用两个不同的命令:一个用于单击,另一个用于保持。我在SmartButton中添加了另一个命令“ClickAndHoldCommand”。您应该将您的命令绑定到此按钮并启用相应的属性。不需要“EnableClickHold”,因为我希望能够将不同的单击命令和按住命令分配给同一按钮。我发现以下编辑可以做到这一点:private void on PreviewMouseLeftButtonUp(对象发送器,MouseButtonEventArgs e){BoO.SimuleSeleSeEnEnguldTimeOutt= Time.ISTabel;ReSeNANDReaveTimeReMeor(;)/ /将其视为鼠标单击(IsMouSereleSeEngReldTimeOutt)命令。执行(CurrdPosiple);你所做的更改对你有用吗?如果是,你可以编辑我的答案并接受它,以便对其他人也有用。:)是的,这可以工作。不过,感谢你的好主意,它应该在按钮控件中。这是一个按钮控件。
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
}