すべてのコントロールは、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;
}
私の質問は次のとおりです。
Enterイベントがテキストボックスで認識されるようにOnAcceptイベントをバイパスする方法はありますか?
テキストボックスの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;
}
したがって、テキストボックスにフォーカスが移るたびに、フォームから承認ボタンを削除します。