当表单没有焦点时,RichTextBox 不会在按下鼠标时开始选择
RichTextBox doesn't start selection on mouse down when the form has not focus
我正在使用 WinForms,在我的表单上有一个 RichTextBox。当我的表单失焦但可见并且我尝试 highlight/select 文本时,它不允许我这样做,直到表单或文本框本身获得焦点。
我试过:
txtInput.MouseDown += (s, e) => { txtInput.Focus(); }
但无济于事,我似乎无法在网上找到有关此问题的任何信息。
当使用记事本等其他程序进行测试时,它确实具有所需的行为。
您可以使用 MouseDown
和 MouseMove
事件手动进行选择。答案基于Taw的第一个想法:
int start = 0;
private void richTextBox1_MouseDown(object sender, MouseEventArgs e)
{
start = richTextBox1.GetTrueIndexPositionFromPoint(e.Location);
richTextBox1.SelectionStart = start;
}
private void richTextBox1_MouseMove(object sender, MouseEventArgs e)
{
if (e.Button.HasFlag(MouseButtons.Left))
{
var current = richTextBox1.GetTrueIndexPositionFromPoint(e.Location);
richTextBox1.SelectionStart = Math.Min(current, start);
richTextBox1.SelectionLength = Math.Abs(current - start);
}
}
这里是 GetTrueIndexPositionFromPoint
方法的代码,取自 Justin:
public static class RichTextBoxExtensions
{
private const int EM_CHARFROMPOS = 0x00D7;
public static int GetTrueIndexPositionFromPoint(this RichTextBox rtb, Point pt)
{
POINT wpt = new POINT(pt.X, pt.Y);
int index = (int)SendMessage(new HandleRef(rtb, rtb.Handle), EM_CHARFROMPOS, 0, wpt);
return index;
}
[DllImport("User32.dll", EntryPoint = "SendMessage", CharSet = CharSet.Auto)]
private static extern IntPtr SendMessage(HandleRef hWnd, int msg, int wParam, POINT lParam);
}
MouseDown
来不及了。
这确实是一种解决方法,但可能就是您所需要的:
private void txtInput_MouseMove(object sender, MouseEventArgs e)
{
txtInput.Focus();
}
或者当然:
txtInput.MouseMove += (s, e) => { txtInput.Focus(); }
事实上,当您移到文本框上时,它可能会从您表单上的其他控件中窃取焦点。如果这是一个问题,您可以通过使用 answers here..
之一检查您的程序是否处于活动状态来防止它
这个解决方案对我不起作用,因为我的 child window 有一个文本框,当我将鼠标悬停在 RichTextBox 上时,它会失去焦点。经过反复试验,我找到了另一个解决方案:
private const int WM_PARENTNOTIFY = 0x0210;
private Form Form = new Form(); // Your Form here!
private RichTextBox RTB = new RichTextBox(); // Your RichTextBox here!
protected override void WndProc(ref Message m)
{
if ((m.Msg == WM_PARENTNOTIFY) && (Form != null) && (Form.Visible) && (GetChildAtPoint(PointToClient(Cursor.Position)) == RTB))
{
RTB.Focus();
}
base.WndProc(ref m);
}
WM_PARENTNOTIFY 消息可以发送多次(包括初始化主表单时),因此请务必检查您的表单是否不为空,否则您将收到异常。
这对我有用;
扩展 RichTextBox 并用它覆盖 WindowProc
protected override void WndProc(ref Message m) {
const int WM_MOUSEACTIVATE = 0x21;
if (m.Msg == WM_MOUSEACTIVATE) {
// Take focus to enable click-through behavior for setting selection
this.Focus();
}
// Let the base handle the event.
base.WndProc(ref m);
}
我正在使用 WinForms,在我的表单上有一个 RichTextBox。当我的表单失焦但可见并且我尝试 highlight/select 文本时,它不允许我这样做,直到表单或文本框本身获得焦点。
我试过:
txtInput.MouseDown += (s, e) => { txtInput.Focus(); }
但无济于事,我似乎无法在网上找到有关此问题的任何信息。
当使用记事本等其他程序进行测试时,它确实具有所需的行为。
您可以使用 MouseDown
和 MouseMove
事件手动进行选择。答案基于Taw的第一个想法:
int start = 0;
private void richTextBox1_MouseDown(object sender, MouseEventArgs e)
{
start = richTextBox1.GetTrueIndexPositionFromPoint(e.Location);
richTextBox1.SelectionStart = start;
}
private void richTextBox1_MouseMove(object sender, MouseEventArgs e)
{
if (e.Button.HasFlag(MouseButtons.Left))
{
var current = richTextBox1.GetTrueIndexPositionFromPoint(e.Location);
richTextBox1.SelectionStart = Math.Min(current, start);
richTextBox1.SelectionLength = Math.Abs(current - start);
}
}
这里是 GetTrueIndexPositionFromPoint
方法的代码,取自 Justin:
public static class RichTextBoxExtensions
{
private const int EM_CHARFROMPOS = 0x00D7;
public static int GetTrueIndexPositionFromPoint(this RichTextBox rtb, Point pt)
{
POINT wpt = new POINT(pt.X, pt.Y);
int index = (int)SendMessage(new HandleRef(rtb, rtb.Handle), EM_CHARFROMPOS, 0, wpt);
return index;
}
[DllImport("User32.dll", EntryPoint = "SendMessage", CharSet = CharSet.Auto)]
private static extern IntPtr SendMessage(HandleRef hWnd, int msg, int wParam, POINT lParam);
}
MouseDown
来不及了。
这确实是一种解决方法,但可能就是您所需要的:
private void txtInput_MouseMove(object sender, MouseEventArgs e)
{
txtInput.Focus();
}
或者当然:
txtInput.MouseMove += (s, e) => { txtInput.Focus(); }
事实上,当您移到文本框上时,它可能会从您表单上的其他控件中窃取焦点。如果这是一个问题,您可以通过使用 answers here..
之一检查您的程序是否处于活动状态来防止它这个解决方案对我不起作用,因为我的 child window 有一个文本框,当我将鼠标悬停在 RichTextBox 上时,它会失去焦点。经过反复试验,我找到了另一个解决方案:
private const int WM_PARENTNOTIFY = 0x0210;
private Form Form = new Form(); // Your Form here!
private RichTextBox RTB = new RichTextBox(); // Your RichTextBox here!
protected override void WndProc(ref Message m)
{
if ((m.Msg == WM_PARENTNOTIFY) && (Form != null) && (Form.Visible) && (GetChildAtPoint(PointToClient(Cursor.Position)) == RTB))
{
RTB.Focus();
}
base.WndProc(ref m);
}
WM_PARENTNOTIFY 消息可以发送多次(包括初始化主表单时),因此请务必检查您的表单是否不为空,否则您将收到异常。
这对我有用;
扩展 RichTextBox 并用它覆盖 WindowProc
protected override void WndProc(ref Message m) {
const int WM_MOUSEACTIVATE = 0x21;
if (m.Msg == WM_MOUSEACTIVATE) {
// Take focus to enable click-through behavior for setting selection
this.Focus();
}
// Let the base handle the event.
base.WndProc(ref m);
}