C# 表单接受块多行文本框输入键事件

C# 表单接受块多行文本框输入键事件,c#,winforms,user-interface,textbox,C#,Winforms,User Interface,Textbox,我的所有控件都继承自一个基类,该基类创建OnAccept和OnCancel并将其分配给Enter键和ESC键 private readonly Button _accept, _cancel; public ViewUserControl() { _accept = new Button(); _cancel = new Button(); _accept.Click += (o, e) => OnAccept(); _cancel.Click += (

我的所有控件都继承自一个基类,该基类创建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();
}
但是,当用户处于多行文本框中时,enter键将启动表单的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事件,以便文本框识别enter事件

有没有办法手动调用textbox的enter事件

手动输入换行符后,如何将光标设置到文本框的末尾

对这些问题的回答将达到我所追求的结果,排序优先于解决方案

更新:

我确实找到了使用
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;
}

因此,每当文本框获得焦点时,我就会从表单中删除accept按钮。

下面是一篇关于如何从外部调用组件事件的帖子


至于Accept事件,您的对话框在控件看到它之前拦截它。唯一可行的方法是添加一个关注焦点变化的表单事件,如果焦点是多行文本控件,则将表单的
AcceptButton
控件设置为null(假设使用
AcceptButton
CancelButton
生成接受/取消事件).

我读了你的前两行,正要对你的答案投否决票,因为这只会导致表单上的事件调用再次被“接受”按钮阻止,但后来我读了你的第二部分,它是金色的。我很尴尬,我是根据你的名声来判断你的回答的。只是金子!非常感谢。