【備忘録】複数行テキストボックスで改行とIME確定を見分ける
要件は以下の通り。
- 複数行入力可能なTextBoxで、
- 日本語入力と英語入力が混ざった状態で、
- IME入力の確定には反応せず、
- 改行を表すEnterキーが押されたことを検知する
(Visual Studio 2019・.NET Framework4.7.2)
要件1
作るだけ。
<Window x:Class="sample.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:local="clr-namespace:sample"
mc:Ignorable="d"
Title="MainWindow" Height="450" Width="800">
<Grid>
<TextBox x:Name="Txtbox" Margin="20,20,20,20" Padding="5,5,5,5" Text=""
AcceptsReturn="True" VerticalScrollBarVisibility="Visible" HorizontalScrollBarVisibility="Auto"/>
</Grid>
</Window>
できた。
要件2~4
確認のため、とりあえず普通に、KeyDownを検知してみる。
<Grid>
<TextBox x:Name="Txtbox" Margin="20,20,20,20" Padding="5,5,5,5" Text=""
AcceptsReturn="True" VerticalScrollBarVisibility="Visible" HorizontalScrollBarVisibility="Auto"
KeyDown="Txtbox_KeyDown"/>
</Grid>
private void Txtbox_KeyDown(object sender, KeyEventArgs e)
{
Console.WriteLine("{0}が押されました!", e.Key.ToString());
}
これでよし。
なんでやねん。
英語入力しか検知できないようです。
作戦変更
Enterキーが物理的に押されているかどうか確認する。CtrlキーやShiftキーが押されていた場合の動作は別途用意すれば良い。
private void Txtbox_KeyDown(object sender, KeyEventArgs e)
{
if (Keyboard.IsKeyDown(Key.Return))
{
Console.WriteLine("Enterキーが押されました!");
}
}
これでよし。
なんでやねん。
先ほどの結果と合わせて考えると、IME確定も改行もKeyDownイベントとして認識されていないっぽい。
さらに作戦変更
検知するイベントを変えます。
<Grid>
<TextBox x:Name="Txtbox" Margin="20,20,20,20" Padding="5,5,5,5" Text=""
AcceptsReturn="True" VerticalScrollBarVisibility="Visible" HorizontalScrollBarVisibility="Auto"
PreviewKeyDown="Txtbox_PreviewKeyDown"/>
</Grid>
private void Txtbox_PreviewKeyDown(object sender, KeyEventArgs e)
{
Console.WriteLine("{0}が押されました!", e.Key.ToString());
}
いけそう。
private void Txtbox_PreviewKeyDown(object sender, KeyEventArgs e)
{
if (e.Key.ToString() == "Return")
{
Console.WriteLine("改行されました!");
// ここ、正しくは、「改行されそう!」ですが、そんなことは気にしない。
}
}
完璧です。
結局
PreviewKeyDownイベントで、e.Key.ToString() == "Return"
を判定してやればよい。
ちなみになぜこれを備忘録として残す事になったかというと、ネットで調べるとTextChangedイベントで、テキストボックスの行数が変わったら改行するというコードが先に出てきて、謎実装しかけるはめになったから。
ちなみに、TextChangedイベントを使うと、最後のEnterが改行として使われてからイベントが発火することになるため、それを許さない要件の場合そもそも使えない。(つまり、「あいうえお」の「い」と「う」の間にカーソルがある状態で、イベントを発火させようとしてEnterすると、先に改行が入るため、「あい\r\nうえお」を処理する羽目になる。)
その点、PreviewKeyDownイベントを使えば、e.Handled = true;
としてやることで、キーイベントの処理を明示的に終了できるので、その心配も無い。
さらにちなみに、KeyEventArgs.ImeProcessedKey
というのもあるみたいだが、これは英語圏で使われる文字を打ったときは全部None
を返してくるので、今回のように改行を検知したいなら、Keyboard.IsKeyDown(Key.Return) && e.ImeProcessedKey.ToString() == "None"
とすれば使えないこともない。
そうではなく、IME確定を検知したいなら、e.ImeProcessedKey.ToString() == "Return"
となるので、強い味方となりそうだ。
Author And Source
この問題について(【備忘録】複数行テキストボックスで改行とIME確定を見分ける), 我々は、より多くの情報をここで見つけました https://qiita.com/NumLocker/items/2d235185228ec3b691ec著者帰属:元の著者の情報は、元のURLに含まれています。著作権は原作者に属する。
Content is automatically searched and collected through network algorithms . If there is a violation . Please contact us . We will adjust (correct author information ,or delete content ) as soon as possible .