问题说明:
一个父控件有n个子控件,不论在哪个子控件上按下键盘,希望首先由父控件进行处理,再决定是否继续由子控件处理。试了几种方法,都很不理想,不能完全实现上述目标。希望大家指教。

解决方案 »

  1.   

    to:  MyLf(不睡觉的鱼) 
    我也不知道啊,我大部份的贴子都是结了贴的。能告诉我你的方法吗?多谢了。
      

  2.   

    假设父控件是Panel,先从Panel继承一个:
    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事件的。
      

  3.   

    楼上的倒是可以实现。只是我双方控件都要子类化,有点麻烦了吧。楼主研究一下windows消息机制吧,看看有不有简单方法,另外看看这个对你有不有帮助:System.Windows.Forms.Application.AddMessageFilter(System.Windows.Forms.IMessageFilter val)
    PreProcessMessage(ref msg)
    WndProc(ref msg)
      

  4.   

    to  MyLf(不睡觉的鱼):
    确如hainang1234(鼠·神·泪) 所言,但对我也很有帮助,谢谢。to hainang1234(鼠·神·泪) 
    多谢提供建议,我会参考一下的。看来还是要再研究研究,如果有结果我会写在这里的。
      

  5.   

    to  bobibobi(bbo) :
    我的目的是由父控件控制键盘消息,并不需要在子控件中写程序。采用MyLf(不睡觉的鱼)的方法,可以说大致解决,但依然需要子类化子控件,也就是说如果想要通用,则需要把Forms中的控件都扩展一下以达到目的。我想,应该只能通过监视消息队列了。但好象消息队列的最小单位是线程,而不是某个Control。现在还知之不详,正在研究中。
      

  6.   

    你把所有加入到父控件的子控件加上一个事件就是了。eg:
    button1.Click += new EventHandler(OnClick1);//这里先调用父控件的事件
    button1.Click += new EventHandler(OnClick2);//这里调用子控件本身事件
      

  7.   

    嗯。是,这实际就是捕获消息的问题。我就是用到了PreProcessMessage这样一个方法。
    试过WndProc(),但拦截不到文本框的输入,也就是说等你拦截的时候,字符已被输入到TextBox中了。
    PreProcessMessage可以做到
    因为简单的事件处理是不能达到这样的功能,只有重写其中的方法。我只是拿出个例子,要做成通用的,就要结合你自己的需求了,这并不复杂啊。我觉得
      

  8.   

    to  MyLf(不睡觉的鱼)
    我的想法最好是不改动子控件,只在父控件层次上截获。目前看来还是只能用Hook一类的了。