Как проверить скольжение TrackBar с помощью удержания и отпускания мыши

2

У меня есть трек-бэк в моей программе WinForms, которая, перемещая его, будет обновляться с огромным и трудоемким методом. Посмотрите на этот код:

trackBar_ValueChanged(object sender, EventArgs e)
{
     this.RefreshData();
}

Эта дорожка содержит 20 шагов. Если пользователь возьмет ползунок гусеницы и потянет его от 20 до 0 в моем случае, "RefreshData" будет выполняться 20 раз, хотя он показывает правильные данные, когда он заканчивает процесс, который является "RefreshData" со значением 0, я хочу сделать что-то вроде он вызывает только "RefreshData" , когда слайдер trackBar был освобожден, поэтому он не будет обрабатывать все шаги в точке разблокировки на панели дорожек.

Любая помощь и советы для достижения этой цели будут опробованы! Спасибо.

  • 1
    мммм, WPF? Silverlight? Winforms? (и т.д)
  • 0
    Это на WinForms
Показать ещё 1 комментарий
Теги:
winforms
mouseevent
trackbar
mouse

4 ответа

1
Лучший ответ

То, что я делал раньше, это использовать таймер. Каждый раз, когда значение TrackBar изменяется, reset таймер, чтобы он срабатывал в 500 мс (или что-то подходящее для вас). Если пользователь изменяет значение перед запуском таймера, он будет reset снова, что означает, что даже если он изменяется несколько раз, таймер будет запускаться только один раз.

Единственное, что можно посмотреть здесь, это то, что таймер будет запускаться в другом потоке, и вы не сможете обновить пользовательский интерфейс из этого потока, поэтому вам придется возвращаться обратно в поток пользовательского интерфейса, чтобы вносить изменения там, Тем не менее, если вы можете перенести большую часть своей дорогой работы на этот фоновый поток, вы будете держать пользовательский интерфейс более продолжительным.

Вот пример кода, который должен дать вам представление о том, что я имею в виду.

public partial class Form1 : Form
{
    private int updateCount;
    private System.Threading.Timer timer;

    public Form1()
    {
        this.InitializeComponent();
        this.timer = new System.Threading.Timer(this.UpdateValue);
    }

    private void UpdateValue(object state)
    {
        // Prevent the user from changing the value while we're doing
        // our expensive operation
        this.Invoke(new MethodInvoker(() => this.trackBar1.Enabled = false));

        // Do the expensive updates - this is still on a background thread
        this.updateCount++;

        this.Invoke(new MethodInvoker(this.UpdateUI));
    }

    private void UpdateUI()
    {
        this.label1.Text = this.updateCount.ToString();

        // Re-enable the track bar again
        this.trackBar1.Enabled = true;
    }

    private void trackBar1_ValueChanged(object sender, EventArgs e)
    {
        this.timer.Change(TimeSpan.FromMilliseconds(500), new TimeSpan(-1));
    }
}

Изменить: здесь используется решение, которое использует таймер winform для выполнения таймингов. Разница здесь в том, что вы заблокируете UI во время выполнения расчета; это может быть или не быть нормально в вашей ситуации.

public partial class Form1 : Form
{
    private int updateCount;
    private Timer timer;

    public Form1()
    {
        this.InitializeComponent();

        this.timer = new Timer();
        this.timer.Interval = 500;
        this.timer.Tick += this.Timer_Tick;
    }

    private void Timer_Tick(object sender, EventArgs e)
    {
        this.timer.Stop();

        this.updateCount++;
        this.label1.Text = this.updateCount.ToString();
    }

    private void trackBar1_ValueChanged(object sender, EventArgs e)
    {
        this.timer.Stop();
        this.timer.Start();
    }
}
  • 0
    @Mike Спасибо, я попробую это, но я искал что-то более простое, может быть, просто с событиями на самом деле.
  • 0
    К сожалению, я не думаю, что вы найдете здесь событие, которое соответствует вашей цели - по сути, вам нужно событие с именем «UserFinishedUpdating», которое срабатывает, когда они прекращают изменять значение, независимо от того, делали ли они это с помощью мыши. или клавиатура. В конечном итоге это то, что даст вам этот код. Дайте мне знать, как вы поживаете, и если вам нужны какие-либо объяснения частей.
Показать ещё 4 комментария
4

Как насчет:

Boolean user_done_updating = false;

private void MytrackBar_ValueChanged(object sender, EventArgs e)
{
    user_done_updating = true;
}

private void MytrackBar_MouseUp(object sender, MouseEventArgs e)
{
    if (user_done_updating)
    {
        user_done_updating = false;
        //Do Stuff
    }
}
1

Рассмотрите возможность выполнения долговременного метода в новом потоке. Сохраните ссылку на этот поток и вызовите Thread.Abort() перед повторным запуском.

0
  • 0
    Проблема с MouseUp том, что он не будет срабатывать, когда пользователь изменяет значение трекбара с помощью клавиатуры. Вам все еще нужно будет обработать ValueChanged для этого случая.
  • 0
    Спасибо Коди, я обновил свой ответ ..

Ещё вопросы

Сообщество Overcoder
Наверх
Меню