问题说明:
一个父控件有n个子控件,不论在哪个子控件上按下键盘,希望首先由父控件进行处理,再决定是否继续由子控件处理。试了几种方法,都很不理想,不能完全实现上述目标。希望大家指教。
一个父控件有n个子控件,不论在哪个子控件上按下键盘,希望首先由父控件进行处理,再决定是否继续由子控件处理。试了几种方法,都很不理想,不能完全实现上述目标。希望大家指教。
解决方案 »
- c#如何设置弹出对话框的访问权限
- [求助]C#如何写嵌套事务
- 程序很不稳定,有时出现以下错误,有时又不出现,奇怪
- 急!!!在线等!!!webservice通过网闸取数据的问题
- 多线程、BeginInvoke、多线程UI
- 关于打开excel模板,将dataset中数据写入模板,另存为别的文件的总结
- C# 问高手如何穿透防火墙
- 对一个表生成多个视图,总是得到最后的视图。
- c# 不能建立新项目了,点新建项目,系统报错:“Automation服务器不能创建新项目”
- 如何用C#编写动态链接库?
- 求助:C#中怎样实现从文体框输入拼音首字母同步查出汉字显示在ListView中
- 高手帮忙解释一下C# 代码的作用!~
我也不知道啊,我大部份的贴子都是结了贴的。能告诉我你的方法吗?多谢了。
public class PanelX:Panel
{
public PanelX()
{}
private bool allowKey = true;
public bool AllowKey
{
get{return allowKey;}
set{allowKey = value;}
}
public void PerformKeyDown(KeyEventArgs e)//触发Panel的KeyDown事件
{
base.OnKeyDown(e);
}
}
在继承的TextBoxX中:
public class TextBoxX:TextBox
{
public TextBoxX()
{}
protected override void OnKeyDown(KeyEventArgs e)
{
PanelX p = this.Parent as PanelX;
if(p != null)
{
if(!p.AllowKey)return;
}
base.OnKeyDown (e);
}
public override bool PreProcessMessage(ref Message msg)
{
int WM_KEYDOWN = 0x0100;
if(msg.Msg == WM_KEYDOWN)
{
PanelX p = this.Parent as PanelX;
p.AllowKey = true;
if(p != null)
{
KeyEventArgs e = new KeyEventArgs((Keys)(int)msg.WParam & Keys.KeyCode);
p.PerformKeyDown(e);
if(!p.AllowKey)
{
msg.WParam = IntPtr.Zero;
return false;
}
}
}
return base.PreProcessMessage (ref msg);
}
}
好了控件已准备好了。
在实现的窗体中,panel(PanelX),txt1(TextBoxX)的KeyDown的事件如下 :
private void panel_KeyDown(object sender, KeyEventArgs e)
{
if(MessageBox.Show("Panel_KeyDown","Test",MessageBoxButtons.YesNo,MessageBoxIcon.Question) == DialogResult.Yes)
this.panel.AllowKey = true;
else
this.panel.AllowKey = false;
}private void txt1_KeyDown(object sender, System.Windows.Forms.KeyEventArgs e)
{
MessageBox.Show("txt1_KeyDown");
}
当在txt1中输入时,会弹出panel的对话框,如果你选择No,则不会触发txt1的KeyDown事件的。
PreProcessMessage(ref msg)
WndProc(ref msg)
确如hainang1234(鼠·神·泪) 所言,但对我也很有帮助,谢谢。to hainang1234(鼠·神·泪)
多谢提供建议,我会参考一下的。看来还是要再研究研究,如果有结果我会写在这里的。
我的目的是由父控件控制键盘消息,并不需要在子控件中写程序。采用MyLf(不睡觉的鱼)的方法,可以说大致解决,但依然需要子类化子控件,也就是说如果想要通用,则需要把Forms中的控件都扩展一下以达到目的。我想,应该只能通过监视消息队列了。但好象消息队列的最小单位是线程,而不是某个Control。现在还知之不详,正在研究中。
button1.Click += new EventHandler(OnClick1);//这里先调用父控件的事件
button1.Click += new EventHandler(OnClick2);//这里调用子控件本身事件
试过WndProc(),但拦截不到文本框的输入,也就是说等你拦截的时候,字符已被输入到TextBox中了。
PreProcessMessage可以做到
因为简单的事件处理是不能达到这样的功能,只有重写其中的方法。我只是拿出个例子,要做成通用的,就要结合你自己的需求了,这并不复杂啊。我觉得
我的想法最好是不改动子控件,只在父控件层次上截获。目前看来还是只能用Hook一类的了。