はじめに
「ネットワーク接続してるような外部アプリ使うと、入力した内容が漏洩する可能性あるよね?
だからtrelloやらなんやらみたいなタスク管理ツールは使っちゃだめだよ」
と言われ、経験ないながら一からタスク管理ツールを作りました。
その最中で壁にぶち当たったので残しておこうと思います。
やりたかったこと
よくある編集アプリのように、
- Ctrl+Sを押されたら
- 1回きりだけ
- 保存処理を呼び出す
- 当然、呼び出し処理の成功確率は100%
これがしたかっただけなのですが、うまくいかずあれやこれや試したので色々残そうと思います。
いい感じに動いたパターン
これだとうまく動きました。
protected override void OnKeyDown(KeyEventArgs e)
{
if (!e.IsRepeat
& Keyboard.GetKeyStates(Key.LeftCtrl).HasFlag(KeyStates.Down)
& Keyboard.GetKeyStates(Key.S).HasFlag(KeyStates.Down))
{
RegistData();
}
}
e.IsRepeatで、キー長押しで呼ばれたのかどうかを判定して何度も登録処理が走るのを防いでいます。
それと、LeftCtrlとSの状態がDownになっているかを、==
ではなくHasFlag
で判定しているのがポイントでした。
デバッグしてわかったんですが、ここの状態はDown, Toggle
みたいな感じで複数の状態を持つことがあるようです。
だめだったパターン
キーの状態を==
で比較 & e.IsRepeatを判定してない
さっき書いた通り、状態が複数になっていると==
ではないため、falseとなり登録処理が走らないことがある。
体感だと成功率70%くらい。
protected override void OnKeyDown(KeyEventArgs e)
{
if (Keyboard.GetKeyStates(Key.LeftCtrl) == KeyStates.Down
& Keyboard.GetKeyStates(Key.S) == KeyStates.Down)
{
RegistData();
}
}
コマンドバインドを使う
押した時にちゃんと動きはするものの、長押しするとするだけ登録処理が呼び出されちゃう。
<Window x:Class="Test.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="clr-namespace:Test"
Title="MainWindow" Height="350" Width="525">
<Window.CommandBindings>
<CommandBinding
Command="{x:Static local:MainWindow.RegistCommand}"
Executed="CommandBinding_Executed"/>
</Window.CommandBindings>
<Window.InputBindings>
<KeyBinding Gesture="Ctrl+S" Command="{Binding RegistCommand}"/>
</Window.InputBindings>
<!-- なんかいろんな要素 -->
</Window>
public RoutedCommand RegistCommand = new RoutedCommand();
// なんかいろんな処理
private void CommandBinding_Executed(object sender, ExecutedRoutedEventArgs e)
{
RegistData();
}
あとがき
ネットで調べてるとe.KeyCode
とかKeys.Control
みたいな書き方がよくあったんだけど、僕の環境だとそもそも存在しないプロパティでした。
(はるか昔にどっかで使ったことある気もする)
見てる感じだとe.KeyCode
に関しては、オブジェクトがSystem.Windows.Forms.KeyEventArgs
じゃなくてSystem.Windows.Input.KeyEventArgs
だったからっぽい。
なんでなんだろう。
textboxとかのOnKeyDownじゃなくてwindow自体の関数だから、とか・・?
普段業務でやってる言語と違って、同じC#かつ同じオブジェクト名でも、微妙に使えたり使えなかったりするからてんやわんやでした。
ただ、自分でアプリを作ると「この機能が欲しい!」→ すぐ作ることできるから良いですね。
楽しい。