我的所有控件都从基类继承,该基类创建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;
}
因此,无论何时文本框获得焦点,我从窗体中删除接受按钮。
我读了你的第一行两行,并且正在降低你的答案,因为它只是导致再次被accept按钮阻止的表单上的事件调用,但是然后我读了你的第二部分,它是黄金。我很尴尬,我以你的名誉来判断你的答案。只是黄金!谢谢。 – Joe 2012-08-10 06:14:29