Обработка события прокрутки на просмотр списка в c # - PullRequest
14 голосов
/ 05 декабря 2009

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

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

Ответы [ 4 ]

19 голосов
/ 05 декабря 2009

Вам нужно будет добавить поддержку в класс 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;
}
1 голос
/ 05 декабря 2009

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

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

0 голосов
/ 26 февраля 2016

На основании сообщения о том, что @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
}

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

0 голосов
/ 11 июня 2010

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

Перехватите событие Loaded из вашего 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)
    {
        ...
    }
...