我的所有控件都从一个基类继承,该基类为Enter和ESC键创建并分配OnAccept和OnCancel。
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而不是在文本框中添加新行(这是预期的行为)。
目前,为了解决这个问题,我必须找到对表单的集中控制,如果是文本框,则手动将换行符放入。但是当我这样做时,光标会重置为文本框的开头。 / p>
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事件,以便文本框识别输入事件?
有没有办法手动调用文本框的输入事件?
手动输入换行符后,如何将光标设置到文本框的末尾?
对这些问题的回答将达到我所追求的结果,优先于解决方案。
更新:
我确实找到了一种方法来使用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;
}
因此,只要文本框获得焦点,我就从表单中删除接受按钮。
答案 0 :(得分:1)
以下是关于如何从外部调用组件事件的帖子。
How can I programmatically generate keypress events in C#?
对于Accept事件,您的对话框会在控件看到它之前拦截它。唯一可行的方法是添加一个监视焦点更改的表单事件,如果焦点是多行文本控件,则将表单的AcceptButton
控件设置为null(假设您使用{{1} }和AcceptButton
生成接受/取消事件。)