我的项目中有一个RepeatButton,可以左右滚动图形。我希望当用户用鼠标按住按钮时,滚动速度会慢慢加快。据我所知,RepeatButton没有内置此功能。有没有一种简单的方法可以在用户按住按钮时慢慢减少按钮的间隔属性,然后在用户松开按钮时重置它?
我认为这是不可能的。
原因是RepeatButton
在引擎盖下的架构方式。基本上,当您按空格键或鼠标左键时,它会根据 Interval
属性的当前设置启动计时器。松开键或鼠标按钮时,计时器将停止。Interval
属性仅定义为香草DependencyProperty
因此它不会执行任何操作来更新计时器的间隔。
您可能会通过反射来调整间隔,并可能停止/重新启动计时器......但我不确定这是否真的值得。
虽然有点技巧,但只要您想要的间隔始终可以表示为某个恒定基间隔的整数倍,通过扩展 RepeatButton 来实现这种效果实际上非常简单。
下面是如何完成此操作的快速示例:
public class AcceleratingRepeatButton : System.Windows.Controls.Primitives.RepeatButton
{
private int _intervalCount = -1;
protected override void OnClick()
{
//Always OnClick for the initial press
if (_intervalCount < 0) {
_intervalCount = -1;
base.OnClick();
} else if (ShouldTriggerRepeat(_intervalCount)) {
base.OnClick();
}
_intervalCount += 1;
}
protected override void OnIsPressedChanged(DependencyPropertyChangedEventArgs e)
{
_intervalCount = -1; //When the button is released, reset the counter
base.OnIsPressedChanged(e);
}
private bool ShouldTriggerRepeat(int count)
{
const int intervalsAtQuarterRate = 16; //For the first 16 intervals, trigger repeats at 1/4 the normal rate
const int intervalsAtHalfRate = 16 + intervalsAtQuarterRate; //the next 16 intervals at 1/2 the rate
if (count < intervalsAtQuarterRate) {
return (count & 7) == 0; //Returns true every 4 intervals
} else if (count < intervalsAtHalfRate) {
return (count & 3) == 0; //Returns true every 2 intervals
} else {
return true;
}
}
}
依赖项属性可用于允许从 xaml 进行配置(为了简洁起见而排除),并且可以在 ShouldTriggerRepeat 中使用更复杂的逻辑来允许更精细的控制。