3

私はnumericUpDownコントロール(Windowsフォーム)を持っています。

ここに画像の説明を入力してください

イベントを聴きたいですValueChanged

プロパティで設定すると動作します。

だが:

上下に「スクロール」できるようにしたいと思います。(これを長くすると速くなります)

「スクロール」が終了したら、スクロール中ではなく、イベントxyzが発生するようにします。

どうやってやるの?

4

4 に答える 4

1

mouseupイベントを使用してみてください。マウスの左ボタンから指を離すと発火するので、理論的には問題は解決するはずです。

[Jamesが編集]フォームでこのコントロールを試してください。

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows.Forms;

namespace Example.CustomControl
{
    /// <summary>
    /// Provides an extra event for the numericUpDown control that fires after the value stops scrolling.
    /// </summary>
    public class NumericDelayedChange : NumericUpDown
    {
        /// <summary>
        /// Flag that the value has actually changed.
        /// </summary>
        /// <devdoc>
        /// Just in case the control was clicked somewhere other than the up/down buttons.
        /// </devdoc>
        private bool valueHasChanged = false;

        /// <summary>
        /// Fires when the value has stopped being scrolled.
        /// </summary>
        public event EventHandler OnAfterScollValueChanged;

        /// <summary>
        /// Captures that value as having changed.
        /// </summary>
        /// <param name="e"></param>
        protected override void OnValueChanged(EventArgs e)
        {
            valueHasChanged = true;
            base.OnValueChanged(e);
        }

        /// <summary>
        /// Captures the mouse up event to identify scrolling stopped when used in combination with the value changed flag.
        /// </summary>
        /// <param name="mevent"></param>
        protected override void OnMouseUp(MouseEventArgs mevent)
        {
            base.OnMouseUp(mevent);
            if (mevent.Button == System.Windows.Forms.MouseButtons.Left)
            {
                PerformOnAfterScollValueChanged();
            }
        }

        /// <summary>
        /// Captures the key up/down events to identify scrolling stopped when used in combination with the value changed flag.
        /// </summary>
        /// <param name="mevent"></param>
        protected override void OnKeyUp(KeyEventArgs e)
        {
            if (e.KeyCode == Keys.Up || e.KeyCode == Keys.Down)
            {
                PerformOnAfterScollValueChanged();
            }
            base.OnKeyUp(e);
        }

        /// <summary>
        /// Checks the value changed flag and fires the OnAfterScollValueChanged event.
        /// </summary>
        private void PerformOnAfterScollValueChanged()
        {
            if (valueHasChanged)
            {
                valueHasChanged = false;
                if (OnAfterScollValueChanged != null) { OnAfterScollValueChanged(this, new EventArgs()); }
            }
        }
    }
}
于 2012-08-02T09:14:20.187 に答える
1

とは何かを定義する必要がありますI'm done with the scroll。これは、スクロールボタンからマウスを削除したか、最後のクリックから一定の時間が経過した可能性があります。いずれにせよ、イベントを実行しないようにすることはできないと思いますが、イベントハンドラーでいくつかのチェックを行うことができます。例えば:

private DateTime? lastClickTime;
public void MyUpDown_ValueChanged(object sender, EventArgs e)
{
    if (lastClickTime != null && DateTime.Now.Subtract(lastClickTime.Value).Seconds > someInterval)
    {
        // Do the work
    }

    lastClickTime = DateTime.Now
}

しかし、私が言ったように、あなたは最初に何であるかを定義する必要がありますI'm done。このコードは完全ではありません。

于 2012-08-02T09:18:13.110 に答える
0

問題に直接アプローチする方法は次のとおりです。次のように、でマウスボタンが押されているかどうかを確認しますControl.MouseButtons

private void numericUpDown1_ValueChanged(object sender, EventArgs e)
    {
        //don't update until done scrolling
        if (Control.MouseButtons == MouseButtons.None)
        {
            // Do the work
        }
    }
于 2014-10-08T23:44:55.593 に答える
0

この問題を解決した方法は次のとおりです。

タスクは「valueIsChanging」フラグをチェックします。このフラグは、ValueChangedイベントによって設定されます。ValueChangedイベントによってこのフラグがTrueに設定されなくなると、whileループが完了し、コードが実行されます。

Task waitForValueSettleTask;
volatile bool valueIsChanging; // marked volaltile since it is access by multiple threads (the GUI thread, and the task)

private void numericUpDown_ValueChanged(object sender, EventArgs e)
{
    valueIsChanging = true;

    if (waitForValueSettleTask == null || waitForValueSettleTask != null &&
    (waitForValueSettleTask.IsCanceled || waitForValueSettleTask.IsCompleted || waitForValueSettleTask.IsFaulted))
    {
        waitForValueSettleTask = Task.Run(() =>
        {
            while (valueIsChanging)
            {
                valueIsChanging = false;
                Thread.Sleep(1000); // Set this to whatever settling time you'd like
            }

            // Your code goes here
        });
    }
}
于 2017-06-27T18:38:52.287 に答える