gpt4 book ai didi

c# - ListView 滚动控件 - 如果用户不滚动,则滚动到底部?

转载 作者:太空狗 更新时间:2023-10-29 23:10:15 26 4
gpt4 key购买 nike

我有一个 .NET 3.5 WinForm,它有一个 ListView,View 设置为 Details 模式。它作为一个长后台任务的可滚动状态项列表。我在底部添加了最新的 ListViewItem(状态条目)。为了确保它被看到,我确保添加后新项目的可见性。这一切都很好; 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);
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();
}
}

奇怪的是,当用户按住滚动条“句柄”时,句柄不会移动(这意味着 View 实际上并没有以编程方式向下滚动),但实际上是这样。

更新:是否可以检测滚动条的位置,即滚动条是否在底部?

最佳答案

解决这个问题的两个步骤:

  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());
}
}
}

现在我们知道用户何时滚动 ListView 。您的下一个问题是确定 ListView 是否空闲;也就是说,如果用户有一段时间没有滚动它。

有多种方法可以做到这一点。为此,我将使用时间戳来指示上次滚动时间:

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();
}
}

关于c# - ListView 滚动控件 - 如果用户不滚动,则滚动到底部?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/7613626/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com