2012-08-10 45 views
0

我的所有控件都从基类继承,该基类创建OnAccept和OnCancel并将其分配给Enter和ESC键。窗体接受块多行文本框输入关键事件

private readonly Button _accept, _cancel; 

public ViewUserControl() 
{ 
    _accept = new Button(); 
    _cancel = new Button(); 

    _accept.Click += (o, e) => OnAccept(); 
    _cancel.Click += (o, e) => OnCancel(); 
} 

// the base function depends on the child functions to implement a accept/cancel function, if it doesn't then those events will fire to the 
// new button and not be used for anything 
public virtual IButtonControl GetAcceptButton() 
{ 
    return _accept; 
} 
public virtual IButtonControl GetCancelButton() 
{ 
    return _cancel; 
} 

protected virtual void OnAccept() { } 
protected virtual void OnCancel() 
{ 
    this.ClosingEvent(); 
} 

然而,当用户是在多行文本,输入键是开球形式的OnAccept而不是将新的一行到文本框中(这是预期的行为)。

目前,为了解决这个问题,我必须找到窗体的焦点控件,如果它是一个文本框,然后手动放入新行。但是当我这样做时,光标重置到文本框的开头。

protected override void OnAccept() 
{ 
    var focused = FindFocusedControl(this); 
    if (focused is TextBox) 
    { 
     focused.Text += Environment.NewLine; 
    } 
    else 
    { 
     base.OnAccept(); 
    } 
} 

public static Control FindFocusedControl(Control control) 
{ 
    var container = control as ContainerControl; 
    while (container != null) 
    { 
     control = container.ActiveControl; 
     container = control as ContainerControl; 
    } 
    return control; 
} 

我的问题是:

有没有办法让输入事件是由文本框认可绕过OnAccept事件?

有没有办法手动调用文本框的输入事件?

手动放置换行符后,如何将光标置于文本框的末尾?

对这些问题中的任何一个的回答都会达到我之后的结果,而不是解决方案。

UPDATE:

我没有找到一个方法来移动插入符(不是光标正如我在原来的问题把它叫做)使用RichTextBox.SelectionStart但是,归根结底,我宁愿一个更优雅的解决方案。

更新2:

对于其他人同样的问题,这就是我现在做的事:

从子控件:

txtDetails.GotFocus += (o,e) => AcceptButtonStatus(false); 
txtDetails.LostFocus += (o, e) => AcceptButtonStatus(true); 

从基本控制:

protected void AcceptButtonStatus(bool enabled) 
{ 
    this.ParentForm.AcceptButton = enabled?_accept:null; 
} 

因此,无论何时文本框获得焦点,我从窗体中删除接受按钮。

回答

1

这是一篇关于如何从外部调用组件事件的文章。

How can I programmatically generate keypress events in C#?

对于接受事件,你的对话框拦截,控制不断看到它之前。唯一可能工作的是添加一个表单事件,用于监视焦点更改,如果焦点是多行文本控件,则将表单的AcceptButton控件设置为空(假设您使用AcceptButtonCancelButton来生成接受/取消事件)。

+0

我读了你的第一行两行,并且正在降低你的答案,因为它只是导致再次被accept按钮阻止的表单上的事件调用,但是然后我读了你的第二部分,它是黄金。我很尴尬,我以你的名誉来判断你的答案。只是黄金!谢谢。 – Joe 2012-08-10 06:14:29