【发布时间】:2011-12-05 18:45:52
【问题描述】:
我有点困惑:
如果用户向上滚动,我们有一个聊天应用程序要求不滚动聊天;我们有一个 scrollInfo 类,它为我们提供了检查滚动条拇指是否位于滚动条底部的能力,以便我们确定是否应该滚动。
不幸的是,滚动聊天有很多不同的方式。可以使用向上/向下滚动条框,或滚动条拇指,或者只使用鼠标滚轮滚动。
但是,如果使用向上/向下箭头,我们没有问题。
而且,如果使用滚动条拇指,VScroll 事件确实会触发,但我们无法确定拇指移动到哪个方向,或者如何检查它是否被按住,而不使用计时器不断查询鼠标左键状态。
最后,如果鼠标滚轮被滚动,虽然我们可以通过查看Delta 属性来判断它的方向,但在处理鼠标滚轮事件后,VScroll 事件仍然会触发。所以,我们基本上发生了重复滚动。
我需要一些帮助。我们的聊天应用如下:
- .NET 4.0 Windows 窗体 C# 应用程序
- 内置于 Visual Studio 2010
- *聊天输出:*
RichTextBox自动格式化输入的文本。
这是我们的逻辑的一个示例,但它不起作用:
用户使用鼠标滚轮向上滚动:当新消息进入时,他们不应向下滚动聊天输出框。相反,当滚动事件发生时,它应该能够检测到滚动拇指的位置,并做出决定。
用户使用 ScrollBar thumb 向上滚动:触发 VScroll 事件,该事件检查滚动条是否位于滚动框的“底部”。并且,如果是,它会执行完整滚动事件,以确保插入符号始终放置在滚动框的末尾,并且是隐藏的(因此 READ ONLY 聊天输出,没有实际闪烁的 I 光束)。
用户使用滚动条上/下箭头滚动:工作正常。 (无需解释,因为它已经在工作了)。
我需要在这里澄清一下,我怎样才能正确检查这些事件?
-------- 编辑澄清 ---------
scrollInfo类的内容:
internal class Scrollinfo
{
internal const uint ObjidVscroll = 0xFFFFFFFB;
[DllImport("user32.dll", SetLastError = true, EntryPoint = "GetScrollBarInfo")]
private static extern int GetScrollBarInfo(IntPtr hWnd,
uint idObject,
ref Scrollbarinfo psbi);
internal static bool CheckBottom(Control rtb, int postion)
{
var info = new Scrollbarinfo();
info.CbSize = Marshal.SizeOf(info);
var chk = GetScrollBarInfo(rtb.Handle,
ObjidVscroll,
ref info);
if (chk == 0)
GetScrollBarInfo(rtb.Handle,
ObjidVscroll,
ref info);
bool isbottom = info.XyThumbBottom
>= (info.RcScrollBar.Bottom - info.RcScrollBar.Top - (info.DxyLineButton + 1));
if (info.DxyLineButton <= 0) isbottom = true;
if (info.XyThumbBottom <= 0) isbottom = true;
return isbottom;
}
}
internal struct Scrollbarinfo
{
internal int CbSize;
internal Rect RcScrollBar;
internal int DxyLineButton;
internal int XyThumbTop;
internal int XyThumbBottom;
internal int Reserved;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 6)]
internal int[] Rgstate;
}
internal struct Rect
{
internal int Left;
internal int Top;
internal int Right;
internal int Bottom;
}}
【问题讨论】:
-
同样让我们感到困惑的是,如果用户使用鼠标滚轮向上滚动,
VScroll事件会按预期触发,但它仍会记录滚动拇指位于底部;而不是注册它已向上滚动。我认为这样做是因为VScroll没有在事件之后触发,而是在事件期间触发,并且滚动拇指还没有改变位置。因此,我们遇到了滚动问题。 -
您在谈论“scrollinfo”类而没有解释它的作用。听起来像是坏了。在 VScroll 事件中使用 GetCharIndexFromPosition 和 GetLineFromCharIndex 来找出用户正在看到的内容。
-
我添加了
scrollinfo的内容,这样你就可以看到它的作用了。
标签: winforms .net-4.0 scroll mouse richtextbox