.net 如何让父控件知道其子控件获得焦点?
假设我有一个在3x3平铺中包含9个控件(TabbedStuffControl)的表单,这些控件包含TabControls,其中包含另一个带有列表框和文本框的控件(StuffControl) 我想知道一个合适的方法,让TabbedTuff控制它的孩子得到了关注?e、 g.用户单击StuffControl的文本框或将某些内容拖动到StuffControl的列表框。最后,表单应该知道哪个选项卡是活动的 我是否需要连接TextBox、ListBox和TabControls的GotFocus事件,然后发送另一个事件以最终让表单知道谁获得了焦点?我认为应该有一种更简单的方法——不知何故,TabbedStuffControl知道它的子对象得到了关注,所以在代码中只有一个地方可以连接.net 如何让父控件知道其子控件获得焦点?,.net,winforms,focus,.net,Winforms,Focus,假设我有一个在3x3平铺中包含9个控件(TabbedStuffControl)的表单,这些控件包含TabControls,其中包含另一个带有列表框和文本框的控件(StuffControl) 我想知道一个合适的方法,让TabbedTuff控制它的孩子得到了关注?e、 g.用户单击StuffControl的文本框或将某些内容拖动到StuffControl的列表框。最后,表单应该知道哪个选项卡是活动的 我是否需要连接TextBox、ListBox和TabControls的GotFocus事件,然后发送
谢谢。您必须使用COM:
// Import GetFocus() from user32.dll
[DllImport("user32.dll", CharSet = CharSet.Auto, CallingConvention = CallingConvention.Winapi)]
internal static extern IntPtr GetFocus();
protected Control FocusControl
{
get
{
Control focusControl = null;
IntPtr focusHandle = GetFocus();
if (focusHandle != IntPtr.Zero)
// returns null if handle is not to a .NET control
focusControl = Control.FromHandle(focusHandle);
return focusControl;
}
}
使用Enter事件(比GotFocus更好)当然是一个好方法。为所有控件订阅一个处理程序,然后在Enter事件处理程序中查找该控件的父级。此示例代码演示了以下方法:
public partial class Form1 : Form {
public Form1() {
InitializeComponent();
wireEnter(this.Controls);
}
private void wireEnter(Control.ControlCollection ctls) {
// Hook Enter event for all controls
foreach (Control ctl in ctls) {
ctl.Enter += ctl_Enter;
wireEnter(ctl.Controls);
}
}
TabbedStuffControl mParent;
private void ctl_Enter(object sender, EventArgs e) {
// Find parent
Control parent = (sender as Control).Parent;
while (parent != null && !(parent is TabbedStuffControl)) parent = parent.Parent;
if (parent != mParent) {
// Parent changed, do something. Watch out for null
//....
mParent = parent as TabbedStuffControl;
}
}
}
谢谢,但是这个属性会告诉我哪个控件有焦点。我想做的是知道某人何时获得焦点,因此我需要一个事件。该库是COM的一部分:。P/Invoke是如何在.NET中使用COM对象的。实际上,P/Invoke只是从.NET调用本机代码——看,您是否认为连接每个控件有点太多了?只是想知道表演会是什么样子。@Icono:Focus事件发生在“人类时间”。您的用户永远不会注意到触发事件所需的~20纳秒。只有一个会开火,不是所有的。