C#根据事件设置活动窗体,刷新窗体并发送到后台-有什么问题?
我正在写一个windows窗体(C#.NET)项目,它将在thinkpad平板电脑上运行。我已经编写了一个自定义文本框,它可以触发设备上的tabtip键盘来帮助进行屏幕输入,但是这很烦人,因为用户必须在不同的模式(数字、文本)和一些其他问题之间不断切换,我希望通过提供自定义表单(键盘)来消除这些问题 它模拟屏幕键盘 我的愿景: 在主窗体上,用户通过点击选择一个文本框,我的键盘窗体显示,是活动窗体并获得焦点。用户可以使用键盘表单将数字/文本发送到主表单上的上一个选定文本框中。如果他将焦点切换回主窗体,它会将焦点移到前面,并将键盘移到后面 我是如何解决的: 我的键盘表单是一个单例,它包含一个注册文本框的方法,该文本框应该触发前面提到的行为。表单包含一个变量,该变量将保存当前(或最后一个)选定的文本框,为此,我注册文本框的OnFocus事件,并根据需要设置该变量C#根据事件设置活动窗体,刷新窗体并发送到后台-有什么问题?,c#,.net,winforms,forms,C#,.net,Winforms,Forms,我正在写一个windows窗体(C#.NET)项目,它将在thinkpad平板电脑上运行。我已经编写了一个自定义文本框,它可以触发设备上的tabtip键盘来帮助进行屏幕输入,但是这很烦人,因为用户必须在不同的模式(数字、文本)和一些其他问题之间不断切换,我希望通过提供自定义表单(键盘)来消除这些问题 它模拟屏幕键盘 我的愿景: 在主窗体上,用户通过点击选择一个文本框,我的键盘窗体显示,是活动窗体并获得焦点。用户可以使用键盘表单将数字/文本发送到主表单上的上一个选定文本框中。如果他将焦点切换回主窗
//part of the full solution
public TextBox CurrentControlInFocus
{
get { return _inFocusControl; }
set
{
if (_inFocusControl != null && _inFocusControl != value)
{
//a new control is being selected
//so we should reset the color on the previous one
//to indicate to the user
//that it is not more the active control
_inFocusControl.BackColor = DefaultColor;
}
// do nothing
if (value == _inFocusControl) return;
_inFocusControl = value;
if (_inFocusControl != null)
{
//highlight the control to indicate
//to the user that this is the current
//active control
_inFocusControl.BackColor = FocusColor;
// activate the keyboard form.
Application.OpenForms[Name].Activate();
}
}
}
我的问题:
键盘已经显示在主窗体后面,我希望行
Application.OpenForms[Name].Activate()
将它带到前面,使活动的形状处于焦点,但发生的是形状闪烁,来到前面,然后返回到主形状后面的先前z顺序
当前不需要的解决方法:
如果我在键盘窗体上将最上面的属性更改为“是”,代码将按预期工作,但这不符合我的标准,即如果主窗体再次检索焦点,键盘应按z顺序向后移动
现在我不知道我还能尝试什么,或者我错过了什么
[可选]由于主窗体上的文本框未处于焦点位置(因为键盘窗体处于焦点位置),插入符号不会显示和动画,有没有比在特定场景中创建带有覆盖绘制事件的自定义文本框并手动绘制插入符号更简单的解决方案?尝试使用
Application.OpenForms[Name].BringToFront()
编辑:
我的猜测是,在控件OnFocus事件中,您不能提供另一种形式的焦点。这将是一件容易测试的事情,我本来可以做到,但我现在没有C#env
编辑2:
来自MSDN
请勿尝试在Enter、GOTCHOCUS、LEVE、LostFocus、Validating或Validated事件处理程序中设置焦点
你可以试着用BeginInvoke来设置焦点,我想它看起来像
BeginInvoke((MethodInvoker)new delegate()
{ Application.OpenForms[Name].Activate(); });
基于@BoldAsLove的建议 我找到了一个适合我的解决方案 正如他提到的MSDN文章,我试图在一个文本框中将焦点从GotFocus事件中切换出来,但它没有按预期工作 然而,通过一个.BeginIvoke,我能够完成从FormA到FormB的焦点切换
public TextBox CurrentControlInFocus
{
get { return _inFocusControl; }
set
{
if (_inFocusControl != null && _inFocusControl != value)
{
_inFocusControl.BackColor = DefaultColor;
}
if (value == _inFocusControl) return;
_inFocusControl = value;
if (_inFocusControl != null)
{
_inFocusControl.BackColor = FocusColor;
#region Important block
var f = Application.OpenForms[Name] ?? Singleton;
// just making sure both handles are created before using an invoke
if (Handle != IntPtr.Zero && _inFocusControl.Handle != IntPtr.Zero)
//call the invoke on the textbox control
_inFocusControl.BeginInvoke((MethodInvoker) (() => {
f.Show(); //show the form
// bring it to front
// it also should raise the event Activated
f.Activate();
}));
#endregion
}
}
}
这是一种非常丑陋的方式。我非常确定,通常一个按钮会触发这样的场景,我遇到了一个异常/边缘情况。我需要在一个GotFocus事件中将焦点更改为另一种形式 表单显示,闪烁两次,然后返回到主表单后面。我确实尝试过带镜头,表演,焦点,最后激活,但同样的行为,形式不停留在前面的焦点。我将尝试用一个极简形式的项目来重现这个问题。我认为它可能是文本框中的焦点导致了这个问题。我实际上是在使用“GotFocus”事件调用我的屏幕上的表单。我将检验你的建议。好的,根据您的编辑,我找到了解决问题的方法。