我正在开发键盘控制,非常简单地嵌入到表单上。使用sendkey类来执行char条目。要使这个功能必须知道以前选择的控件。
答案 0 :(得分:5)
以下内容应该可以解决问题:
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
namespace DragDropTest
{
public partial class LostFocusTestForm : Form
{
private Control _lastControl;
public LostFocusTestForm()
{
InitializeComponent();
TrapLostFocusOnChildControls(this.Controls);
}
private void finalTextBox_Enter(object sender, EventArgs e)
{
MessageBox.Show("From " + _lastControl.Name + " to " + this.ActiveControl.Name);
}
private void AllLostFocus(object sender, EventArgs e)
{
_lastControl = (Control)sender;
}
private void TrapLostFocusOnChildControls(Control.ControlCollection controls)
{
foreach (Control control in controls)
{
control.LostFocus += new EventHandler(AllLostFocus);
Control.ControlCollection childControls = control.Controls;
if (childControls != null)
TrapLostFocusOnChildControls(childControls);
}
}
}
}
答案 1 :(得分:2)
扩大大卫的答案。这是您可以使用Enter事件和变量来存储最后一个控件的方法:
using System;
using System.Windows.Forms;
namespace WindowsFormsApplication1
{
public partial class Form1 : Form
{
Control lastControlEntered = null;
public Form1()
{
InitializeComponent();
foreach (Control c in Controls)
if (!(c is Button)) c.Enter += new EventHandler(c_Enter);
}
void c_Enter(object sender, EventArgs e)
{
if (sender is Control)
lastControlEntered = (Control)sender;
}
private void button1_Click(object sender, EventArgs e)
{
label1.Text = lastControlEntered == null ? "No last control" : lastControlEntered.Name;
}
}
}
要运行此代码,请在Visual Studio中向表单添加一些文本框和其他控件,然后添加一个按钮和一个标签,并将按钮的单击处理程序附加到button1_Click。按下按钮时,按下按钮之前所在的最后一个控件将显示在标签中。编辑此代码以满足您的需求。
答案 2 :(得分:0)
您需要将其存储在变量中。对于Control对象,有“Enter”事件
答案 3 :(得分:0)
另一种策略是使用扩展方法来扩展Control.ControlCollection,然后使用一些间接(委托)递归地解析Form的Controls集合,添加一个更新静态变量的特殊“Enter”处理程序。通过跟踪先前的主动控制和当前的主动控制,您可以获得所需的...如果我完全理解您的问题。这是一个需要FrameWork 3.5或4.0的示例。
//在公共静态类中:
using System;
using System.Collections.Generic;
using System.Windows.Forms;
private static EventHandler _event;
// extension method on Control.ControlCollection
public static void SetEnterEvent(this Control.ControlCollection theCollection, EventHandler theEvent)
{
_event = theEvent;
recurseSetEnter(theCollection);
}
// recurse all the controls and add the Enter Event :
public static void recurseSetEnter(Control.ControlCollection aCollection)
{
foreach (Control theControl in aCollection)
{
// "weed out" things like internal controls of the NumericUpDown Control
// String.IsNullOrWhiteSpace is FrameWork 4.0
// use Trim() followed by String.IsNullOrEmpty for FrameWork 3.5
if (!String.IsNullOrWhiteSpace(theControl.Name))
{
Console.WriteLine("setting enter handler for : " + theControl.Name + " : " + theControl.GetType().ToString());
theControl.Enter += _event;
}
if (theControl.Controls.Count > 0) recurseSetEnter((Control.ControlCollection)theControl.Controls);
}
}
那么我们如何使用它:在表单中:
首先让我们定义一个实际的事件处理程序,它将在任何控件上遇到Enter事件时实际执行:
我们将当前的活动控件和先前的活动控件保留在公共静态变量中:
public static Control theActiveControl = null;
public static Control thePreviousControl = null;
这是进行更新的代码:
private void control_enter(object sender, EventArgs e)
{
thePreviousControl = theActiveControl;
theActiveControl = sender as Control;
Console.WriteLine("Active Control is now : " + theActiveControl.Name);
}
现在,在Form_Load事件或其他地方,我们只需要连接事件:
// in a Form**
// define a delegate for the enter Event
private event EventHandler enter = delegate { };
// in the form load even or somewhere : assign an actual event handler to the delegate
enter += new EventHandler(control_enter);
最后,我们在Form的Controls Collection上调用扩展方法:
this.Controls.SetEnterEvent(enter);
讨论:WinForm维护一个'ActiveControl集合:这将包含一个指向最近激活的控件的指针,无论它在一个或多个容器中嵌套有多深:...某些容器(如Panel)不注册为这个集合中的活动控件即使它们具有Leave / Enter事件......控件将在使用/选择/输入/聚焦等时成为ActiveControl。不幸的是,没有“ActiveControlChanged”事件。
[编辑]在实践中我正在使用“过滤器”开发这个,所以我可以有选择地跳过某些对象类型,或者,例如,查找一些“键”(在控件名称或其标签中)以确定是否或不要添加处理程序......是的......这是一个实验。 [编辑]
[编辑]请注意,像PictureBox这样的控件没有公开'Enter事件,但是这段代码不会导致错误:我的远程目标是找到一种方法来测试,而不是反射,特定控件是否确实暴露了在我安装之前给出了'事件:因为我认为让PictureBox这样的事情摆脱困境是不好的做法。到目前为止,我没有找到“container-ness”的正确“测试”(“是ControlContainer”结果是错误的轨道)。例如,您可能还会注意到,Panel会显示一个'Enter事件,但只有在激活Panel中的某个Control时才会触发它。 [编辑]
希望这有帮助。我相信这可能会使用Lambdas更优雅地写出来,但是在这方面我还是一只以幼虫为食的“幼虫”:)
答案 4 :(得分:0)
你可以这样做 string activeControl = this.ActiveControl.Name
答案 5 :(得分:-2)
您必须自己跟踪。编写一个简单的UIElement.LostFocus
处理程序,将发件人置于“具有焦点的最后一个控件”变量,然后就完成了。
注意:WPF。不确定你是在做那个还是WinForms。我最近做了很多WPF我在大脑上有它。