Обработка события прокрутки в listview в С#
У меня есть listview, который генерирует миниатюру с помощью фонаря. Когда прокрутка списка прокручивается, я хочу приостановить работу фонового рабочего и получить текущее значение прокрученной области, когда пользователь прекратил прокрутку списка, возобновите работу фонового рабочего, начиная с элемента, в соответствии со значением прокрученной области.
Можно ли обрабатывать событие прокрутки списка? если да, то как? если нет, то какая хорошая альтернатива в соответствии с тем, что я описал выше?
Ответы
Ответ 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 в случае поднятого может быть изменено, чтобы содержать более полезную информацию. Мне просто нужно было знать, что мой контроль был прокручен!