Управление прокруткой ListView - прокрутить вниз, если пользователь не прокручивает? - PullRequest
5 голосов
/ 30 сентября 2011

У меня есть .NET 3.5 WinForm, у которой есть ListView с представлением, установленным в режиме сведений.Он функционирует как прокручиваемый список элементов состояния в длинной фоновой задаче.У меня есть последний ListViewItem (статус записи), добавленный в нижней части.Чтобы убедиться, что это видно, я добавляю видимость нового элемента после добавления.Это все работает отлично;представление списка автоматически прокручивается вниз, чтобы показать самый последний элемент.

private void AddListItem(DateTime timestamp, string message, int index)
{
    var listItem = new ListViewItem(timestamp.ToString());
    listItem.SubItems.Add(message);
    statusList.Items.Insert(index, listItem);
    statusList.Items[statusList.Items.Count - 1].EnsureVisible();
}

Проблема заключается в том, что если пользователь прокручивает вверх, чтобы просмотреть старые сообщения, ListView будет прокручиваться вниз, чтобы создать новый элемент.видимый по мере его поступления. Есть ли способ управления этим поведением, чтобы проверить, взаимодействует ли пользователь с полосой прокрутки (в частности, если он удерживает кнопку мыши на полосе прокрутки)?Вероятно, это также приемлемо для обнаружения, если прокрутка всегда внизу.если его нет внизу, то я бы не обеспечил видимость последнего элемента.Что-то вроде:

private void AddListItem(DateTime timestamp, string message, int index)
{
    var listItem = new ListViewItem(timestamp.ToString());
    listItem.SubItems.Add(message);
    statusList.Items.Insert(index, listItem);
    if (!statusList.IsScrollbarUserControlled)
    {
        statusList.Items[statusList.Items.Count - 1].EnsureVisible();
    }
}

Странно то, что когда пользователь удерживает «ручку» полосы прокрутки на месте, ручка не перемещается (это означает, что представление фактически не прокручивается программно вниз),но в действительности это.

Обновление : возможно ли определить положение полосы прокрутки, т. е. находится ли она внизу или нет?

Ответы [ 2 ]

4 голосов
/ 01 октября 2011

Два шага к решению этой проблемы:

  1. У WinForms ListView нет события Scrolled.Нам нужно определить его.
  2. Определение, когда ListView бездействует, и вызов EnsureVisible только тогда, когда он простаивает некоторое время.

Для первой проблемы унаследуйте новый классиз ListView переопределите насос сообщений Windows и создайте событие, когда пользователь прокручивает его:

public class MyListView : ListView
{
    public event EventHandler<EventArgs> Scrolled;

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

        const int wm_vscroll = 0x115;
        if (m.Msg == wm_vscroll && Scrolled != null)
        {
            Scrolled(this, new EventArgs());
        }
    }
}

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

Есть несколько способов сделать это.Для этой цели я просто буду использовать отметку времени, чтобы указать время последней прокрутки:

private DateTime lastScrollTime;

...

listView.Scrolled += delegate { lastScrollTime = DateTime.Now };

...

private void AddListItem(DateTime timestamp, string message, int index)
{
    var listItem = new ListViewItem(timestamp.ToString());
    listItem.SubItems.Add(message);
    statusList.Items.Insert(index, listItem);

    // Scroll down only if the list view is idle.
    var idleTime = TimeSpan.FromSeconds(5);
    var isListViewIdle = DateTime.Now.Subtract(this.lastScrollTime) > idleTime;
    if (isListViewIdle)
    {
       statusList.Items[statusList.Items.Count - 1].EnsureVisible();
    }
}
2 голосов
/ 30 сентября 2011

Сравните, скажем, с ProcMon от SysInternals.Установите флажок «Автопрокрутка», чтобы пользователь мог отключить его.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...