获取 Winforms 文本框的滚动条滚动值 (C#)
Get the value of a scrollbar's scroll for a Winforms Text Box (C#)
我正在使用 C# 创建一个 Windows 表单应用程序
我需要一个复选框在用户滚动到文本框底部之前显示为灰色。
如何获取文本框滚动条位置的值?
这是一个告诉您最后一行是否可见的函数:
bool LastLineVisible(TextBox textbox)
{
Point lowPoint = new Point(3, textbox.ClientSize.Height - 3);
int lastline = textbox.Lines.Count() - 1;
int charOnLastvisibleLine = textbox.GetCharIndexFromPosition(lowPoint);
int lastVisibleLine = textbox.GetLineFromCharIndex(charOnLastvisibleLine);
return lastVisibleLine >= lastline;
}
您仍然需要检测滚动事件本身。请参阅 here 了解如何检测滚动。
这应该是一个 RichTextBox,因此您可以使用其 SelectionProtected 属性 来确保用户无法更改文本。它没有滚动事件,但可以通过覆盖 WndProc() 并检测 WM_VSCROLL 消息来添加。除非 WordWrap 属性 设置为 False,否则检查最后一行是否像 @TaW 那样可见是不可靠的。更容易检查滚动条的状态。
向您的项目添加一个新的 class 并粘贴如下所示的代码。编译。将工具箱顶部的新控件拖放到窗体上。订阅 LicenseViewed 事件并将复选框“已启用 属性 设置为 true。如果我不指出只有律师才认为这是个好主意,那我就失职了,用户发现这类文本框普遍令人讨厌并且非常讨厌它们。您只有一次机会创造良好的第一印象。
using System;
using System.Windows.Forms;
using System.Runtime.InteropServices;
class LicenseBox : RichTextBox {
public event EventHandler LicenseViewed;
public override string Text {
get { return base.Text; }
set { base.Text = value; textChanged(); }
}
public new string Rtf {
get { return base.Rtf; }
set { base.Rtf = value; textChanged(); }
}
private bool eventFired;
private void textChanged() {
this.SelectAll();
this.SelectionProtected = true;
this.SelectionStart = this.SelectionLength = 0;
eventFired = false;
checkScrollbar();
}
private void checkScrollbar() {
if (eventFired || !this.IsHandleCreated) return;
var pos = new ScrollInfo();
pos.cbSize = Marshal.SizeOf(pos);
pos.fMask = 7;
if (!GetScrollInfo(this.Handle, SB_VERT, ref pos)) return;
if (pos.nPos >= pos.nMax - pos.nPage) {
if (LicenseViewed != null) LicenseViewed(this, EventArgs.Empty);
eventFired = true;
}
}
protected override void WndProc(ref Message m) {
base.WndProc(ref m);
if (m.Msg == WM_VSCROLL || m.Msg == WM_MOUSEWHEEL) checkScrollbar();
}
// Pinvoke
private const int WM_VSCROLL = 0x115;
private const int WM_MOUSEWHEEL = 0x20A;
private const int SB_VERT = 1;
private struct ScrollInfo {
public int cbSize, fMask, nMin, nMax, nPage, nPos, nTrackPos;
}
[DllImport("user32.dll", SetLastError = true)]
private static extern bool GetScrollInfo(IntPtr hwnd, int bar, ref ScrollInfo pos);
}
我正在使用 C# 创建一个 Windows 表单应用程序
我需要一个复选框在用户滚动到文本框底部之前显示为灰色。
如何获取文本框滚动条位置的值?
这是一个告诉您最后一行是否可见的函数:
bool LastLineVisible(TextBox textbox)
{
Point lowPoint = new Point(3, textbox.ClientSize.Height - 3);
int lastline = textbox.Lines.Count() - 1;
int charOnLastvisibleLine = textbox.GetCharIndexFromPosition(lowPoint);
int lastVisibleLine = textbox.GetLineFromCharIndex(charOnLastvisibleLine);
return lastVisibleLine >= lastline;
}
您仍然需要检测滚动事件本身。请参阅 here 了解如何检测滚动。
这应该是一个 RichTextBox,因此您可以使用其 SelectionProtected 属性 来确保用户无法更改文本。它没有滚动事件,但可以通过覆盖 WndProc() 并检测 WM_VSCROLL 消息来添加。除非 WordWrap 属性 设置为 False,否则检查最后一行是否像 @TaW 那样可见是不可靠的。更容易检查滚动条的状态。
向您的项目添加一个新的 class 并粘贴如下所示的代码。编译。将工具箱顶部的新控件拖放到窗体上。订阅 LicenseViewed 事件并将复选框“已启用 属性 设置为 true。如果我不指出只有律师才认为这是个好主意,那我就失职了,用户发现这类文本框普遍令人讨厌并且非常讨厌它们。您只有一次机会创造良好的第一印象。
using System;
using System.Windows.Forms;
using System.Runtime.InteropServices;
class LicenseBox : RichTextBox {
public event EventHandler LicenseViewed;
public override string Text {
get { return base.Text; }
set { base.Text = value; textChanged(); }
}
public new string Rtf {
get { return base.Rtf; }
set { base.Rtf = value; textChanged(); }
}
private bool eventFired;
private void textChanged() {
this.SelectAll();
this.SelectionProtected = true;
this.SelectionStart = this.SelectionLength = 0;
eventFired = false;
checkScrollbar();
}
private void checkScrollbar() {
if (eventFired || !this.IsHandleCreated) return;
var pos = new ScrollInfo();
pos.cbSize = Marshal.SizeOf(pos);
pos.fMask = 7;
if (!GetScrollInfo(this.Handle, SB_VERT, ref pos)) return;
if (pos.nPos >= pos.nMax - pos.nPage) {
if (LicenseViewed != null) LicenseViewed(this, EventArgs.Empty);
eventFired = true;
}
}
protected override void WndProc(ref Message m) {
base.WndProc(ref m);
if (m.Msg == WM_VSCROLL || m.Msg == WM_MOUSEWHEEL) checkScrollbar();
}
// Pinvoke
private const int WM_VSCROLL = 0x115;
private const int WM_MOUSEWHEEL = 0x20A;
private const int SB_VERT = 1;
private struct ScrollInfo {
public int cbSize, fMask, nMin, nMax, nPage, nPos, nTrackPos;
}
[DllImport("user32.dll", SetLastError = true)]
private static extern bool GetScrollInfo(IntPtr hwnd, int bar, ref ScrollInfo pos);
}