Подтвердить что ты не робот

Обработка события прокрутки в listview в С#

У меня есть listview, который генерирует миниатюру с помощью фонаря. Когда прокрутка списка прокручивается, я хочу приостановить работу фонового рабочего и получить текущее значение прокрученной области, когда пользователь прекратил прокрутку списка, возобновите работу фонового рабочего, начиная с элемента, в соответствии со значением прокрученной области.

Можно ли обрабатывать событие прокрутки списка? если да, то как? если нет, то какая хорошая альтернатива в соответствии с тем, что я описал выше?

4b9b3361

Ответ 1

Вам нужно будет добавить поддержку класса ListView, чтобы вы могли получать уведомления о событиях прокрутки. Добавьте новый класс в свой проект и вставьте код ниже. Компиляция. Отбросьте новый элемент управления listview с верхней части панели инструментов на свою форму. Внедрите обработчик для нового события Scroll.

using System;
using System.Windows.Forms;

    class MyListView : ListView {
      public event ScrollEventHandler Scroll;
      protected virtual void OnScroll(ScrollEventArgs e) {
        ScrollEventHandler handler = this.Scroll;
        if (handler != null) handler(this, e);
      }
      protected override void WndProc(ref Message m) {
        base.WndProc(ref m);
        if (m.Msg == 0x115) { // Trap WM_VSCROLL
          OnScroll(new ScrollEventArgs((ScrollEventType)(m.WParam.ToInt32() & 0xffff), 0));
        }
      }
    }

Помните, что позиция прокрутки (ScrollEventArgs.NewValue) не имеет смысла, она зависит от количества элементов в ListView. Я заставил его выполнить 0. Следуя вашим требованиям, вы хотите посмотреть уведомление ScrollEventType.EndScroll, чтобы узнать, когда пользователь прекратил прокрутку. Все остальное поможет вам обнаружить, что пользователь начал прокрутку. Например:

ScrollEventType mLastScroll = ScrollEventType.EndScroll;

private void myListView1_Scroll(object sender, ScrollEventArgs e) {
  if (e.Type == ScrollEventType.EndScroll) scrollEnded();
  else if (mLastScroll == ScrollEventType.EndScroll) scrollStarted();
  mLastScroll = e.Type;
}

Ответ 2

Смотрите это сообщение Событие прокрутки ListView

Используйте класс родного окна для прослушивания для сообщений прокрутки на ListBox. Будет работать с любым управлением.

Ответ 3

Захват события прокрутки теперь легко выполняется в .net 4.

Поймайте загруженное событие из списка ListView (m_ListView) и выполните следующее:

        if (VisualTreeHelper.GetChildrenCount(m_ListView) != 0)
        {
            Decorator border = VisualTreeHelper.GetChild(m_ListView, 0) as Decorator;
            ScrollViewer sv = border.Child as ScrollViewer;
            sv.ScrollChanged += ScrollViewer_ScrollChanged;
        }

затем выполните свою функцию ScrollViewer_ScrollChanged:

    private void ScrollViewer_ScrollChanged(object sender, ScrollChangedEventArgs e)
    {
        ...
    }

Ответ 4

Основываясь на сообщении, что @Adriaan Stander опубликовал мой класс для создания событий прокрутки ниже.

internal class ControlScrollListener : NativeWindow, IDisposable
{
    public event ControlScrolledEventHandler ControlScrolled;
    public delegate void ControlScrolledEventHandler(object sender, EventArgs e);

    private const uint WM_HSCROLL = 0x114;
    private const uint WM_VSCROLL = 0x115;
    private readonly Control _control;

    public ControlScrollListener(Control control)
    {
        _control = control;
        AssignHandle(control.Handle);
    }

    protected bool Disposed { get; set; }

    public void Dispose()
    {
        Dispose(true);
        GC.SuppressFinalize(this);
    }

    private void Dispose(bool disposing)
    {
        if (Disposed) return;

        if (disposing)
        {
            // Free other managed objects that implement IDisposable only
        }

        // release any unmanaged objects
        // set the object references to null
        ReleaseHandle();

        Disposed = true;
    }

    protected override void WndProc(ref Message m)
    {
        HandleControlScrollMessages(m);
        base.WndProc(ref m);
    }

    private void HandleControlScrollMessages(Message m)
    {
        if (m.Msg == WM_HSCROLL | m.Msg == WM_VSCROLL)
        {
            if (ControlScrolled != null)
            {
                ControlScrolled(_control, new EventArgs());
            }
        }
    }
}

Используйте его так...

Объявить поле:

 private ControlScrollListener _processListViewScrollListener;

Создайте его с помощью элементов управления, которые вам необходимо знать:

_processListViewScrollListener = new ControlScrollListener(ProcessesListView);

Провод в обработчике:

_processListViewScrollListener.ControlScrolled += ProcessListViewScrollListener_ControlScrolled;

Обработчик события:

void ProcessListViewScrollListener_ControlScrolled(object sender, EventArgs e)
{
    // do what you need to do
}

Событие args в случае поднятого может быть изменено, чтобы содержать более полезную информацию. Мне просто нужно было знать, что мой контроль был прокручен!