質問

I have a RepeatButton in my project that scrolls a graph left and right. I want the scroll to slowly speed up as the user holds the button with their mouse. As far as I can tell, RepeatButton doesn't have this feature built in. Is there an easy way I could slowly decrease the interval property of the button while the user is holding it, and then reset it when the user lets off the button?

役に立ちましたか?

解決

I don't think this is possible.

Reason being is the way the RepeatButton is architected under the hood. Basically, when you press the spacebar or press the left mouse button, it starts a timer based on the current settings of the Interval property. When you release the key or mouse button, the timer is stopped. The Interval property is just defined as a vanilla DependencyProperty so it doesn't do anything to update the interval of the timer.

You could probably hack something up with reflection to adjust the interval and maybe stop/restart the timer... but I'm not sure it would really be worth it.

他のヒント

Although a bit of a hack, this effect is actually pretty simple to achieve by extending RepeatButton as long as your desired interval can always be expressed as an integer multiple of some constant base interval.

Here is a quick example of how this can be done:

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;
        }
    }
}

Dependency properties can be used to allow configuration from xaml (excluded in favor of brevity), and more complex logic can be used within ShouldTriggerRepeat to allow more fine-tuned control.

ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top