winform mouseleave 不触发问题,以及textbox lostFucos事件

2024-12-28 17:15:22
推荐回答(2个)
回答1:

第一个问题,你仔细看一下,是不是有什么东西覆盖在label的左上角了。可能是某个控件的边界恰好挡住了那么一点。我这边试验没有问题。

第二个问题,你可以调用Win32 API直接强制丢失焦点。代码如下

// 获取鼠标屏幕位置用的Struct
[StructLayout(LayoutKind.Sequential)]
public struct POINT
{
public int X;
public int Y;

public POINT(int x, int y)
{
this.X = x;
this.Y = y;
}

public static implicit operator Point(POINT p)
{
return new Point(p.X, p.Y);
}

public static implicit operator POINT(Point p)
{
return new POINT((int)p.X, (int)p.Y);
}
}

public partial class Form1 : Form
{
private const int WM_MOUSEACTIVE = 0x21;

[DllImport("user32.dll")]
public static extern IntPtr SetFocus(IntPtr hWnd);

[DllImport("user32.dll")]
public static extern bool GetCursorPos(out POINT lpPoint);

public Form1()
{
InitializeComponent();
textBox1.LostFocus += new EventHandler(textBox1_LostFocus);
}

private void textBox1_LostFocus(object sender, EventArgs e)
{
label1.Text = "Lost!";
}

private void label1_MouseEnter(object sender, EventArgs e)
{
label1.Text = "Enter!";
}

private void label1_MouseLeave(object sender, EventArgs e)
{
label1.Text = "Leave!";
}

protected override void WndProc(ref Message m)
{
// 如果是鼠标点击的消息,就强制丢失焦点
if (m.Msg == WM_MOUSEACTIVE)
{
POINT point = new POINT();
GetCursorPos(out point);
// 获取鼠标点击的位置(被隐式转换为System.Drawing.Point)
Point position = textBox1.PointToClient(point);
// 只要点击的不是textBox1,就强制丢失焦点
if (!textBox1.ClientRectangle.Contains(position))
{
SetFocus(IntPtr.Zero);
}
}
base.WndProc(ref m);
}
}

回答2:

1,2得事件都应该触发,原因可能是在触发前在别的程序发生异常,并没有捕获。