今回のネタは今までの「xamlとC#の異種統合問題としてのWPF」という社会学的な論点ではなく、よりプラグマティックで純粋にプログラミング関連の話題、

 

WinformsとWPFmにおけるリアルタイムキー入力の相違

 

という気楽なお話です。

 

電卓」プログラムは仕様として、「電卓ウィンドウのキーボードをマウスでクリックする」のみならず、「PCのキーボードから直接入力する」ことができます。

 

WinFormsベースのWinCalcでは

Formクラスから派生したForm_Calcクラスのキー入力イベントであるKeyPressメソッド

 

        //Form上で「文字キー」が押されたとき
        private void Form1_KeyPress(object sender, KeyPressEventArgs e)
 

を使い、入力文字はchar型の"e.KeyChar"でswitch文を書きました。

 

所がWPFベースのWpf_Calcでは

元となるWindowクラスにはキー関連イベントはなく、「WPF ウィンドウ キー入力イベント」でググるとご本家の「入力の概要」があり、他の記事も読んでみると「Keyboard クラスの KeyDown メソッドを使う」ようで、具体的には xamlプログラムの x:WIndow の定義に

 

    KeyDown="WpfCalc_KeyPress"(解説:""内は関数(メソッド)名-WinCalcから流用したので同じ名前になっています。)

 

とするだけでウィンドウにフォーカスがある場合のキーボード入力ができるみたいです。(この段階で、「WPFのKeyDownのキーの値はKey列挙型でchar型ではない」という最低限の認識はありました。)

 

Ah, huh!!! "WinForms’ KeyPress is WPF's KeyDown!"

 

等と早とちりしたのが今回の運の尽きでした。結局は「似て非なるWinFormsのC#とWPFのC#」の話題なので、「xamlとC#の異種統合問題としてのWPF」にも関連してくるのかもしれません。では、

 

Have fun!

 

【Copilotとの対話】

Q: WPFのKeyDownイベントに関連して、KeyEventArgs eのe.Key列挙型で「=」「(」「)」を判定する際、
e.Key == Key.D0 & ModifierKeys.Shift
のような書き方では失敗するのでしょうか?


A:  結論から言うと、その書き方では必ず失敗します。理由は、WPF の KeyEventArgs が 「押されたキーそのもの」しか返さず、Shift で変化した記号は返さないからです。

🎯 なぜ失敗するのか(本質)
あなたが書いた式:
e.Key == Key.D0 & ModifierKeys.Shift

これは WPF の仕組みと合っていません。
✔ e.Key は「物理キー」を返す
Shift を押していても、
Key.D0 は 0 のキーであり、
「)」や「=」には変化しません。
つまり:
- Shift + 0 → e.Key == Key.D0(値は変わらない)
- Shift + = → e.Key == Key.OemPlus(Shift の有無は反映されない)
✔ Shift の判定は Keyboard.Modifiers を使う
ModifierKeys.Shift は 単なる列挙値であり、e.Key と比較しても意味がありません。

🧩 正しい判定方法
✔ 「=」の判定(Shift なしの =)
if (e.Key == Key.OemPlus && Keyboard.Modifiers == ModifierKeys.None)
{
    // =
}

✔ 「+」の判定(Shift + =)
if (e.Key == Key.OemPlus && Keyboard.Modifiers == ModifierKeys.Shift)
{
    // +
}

✔ 「(」の判定(Shift + 9)
if (e.Key == Key.D9 && Keyboard.Modifiers == ModifierKeys.Shift)
{
    // (
}

✔ 「)」の判定(Shift + 0)
if (e.Key == Key.D0 && Keyboard.Modifiers == ModifierKeys.Shift)
{
    // )
}

🧠 さらに重要なポイント
WPF の KeyEventArgs は 文字ではなくキーコードを扱うので、「Shift を押した結果の文字」を直接判定することはできません。つまり:
- キー(Key)
- 修飾キー(Shift, Ctrl, Alt)
を組み合わせて判定するしかない。

🌱 (私の名) さん向けの補足
Win32 の WM_CHAR に慣れていると、「Shift の結果としての文字」が来ない WPF の仕様はかなり違和感があると思う。WPF は「キー入力」と「文字入力」を完全に分離していて、
- KeyDown → 物理キー
- TextInput → 実際の文字(IME も含む)
という構造になっている。もし「文字としての =, (, ) を取りたい」なら、TextInput を使うほうが自然。

必要なら、電卓アプリに最適な KeyDown / TextInput の使い分けもまとめて案内できるよ。


Q: では、「(」を
Key.D9 && Keyboard.Modifiers.HasFlag(ModifierKeys.Shift)
「)」を
Key.D0 && Keyboard.Modifiers.HasFlag(ModifierKeys.Shift)
と言われたのですが正しいですか?(JISキーボード上では'8'と'9'のキーにありますが???)
また'='を判定するにはどう表記すればよいでしょう?


A: WPF の KeyDown は 「押された物理キー」しか返さないので、JIS キーボード上の刻印位置とは無関係に、US 配列のキーコード体系(=スキャンコード)で判定されます。だから、あなたが感じた「JIS では ( と ) は 8 と 9 のキーなのに、D9 と D0 で判定するの?」という違和感はもっともなんだけど、WPF の Key 列挙は JIS 配列を考慮していないため、実際にはあなたが示した判定方法が正しい。

🎯 結論:あなたの書き方は正しい
✔ 「(」の判定(Shift + 9)
e.Key == Key.D9 && Keyboard.Modifiers.HasFlag(ModifierKeys.Shift)

✔ 「)」の判定(Shift + 0)
e.Key == Key.D0 && Keyboard.Modifiers.HasFlag(ModifierKeys.Shift)

JIS 配列では
- Shift + 8 → (
- Shift + 9 → )
だけど、WPF の Key は US 配列のキーコードを返すので、
- ( → D9
- ) → D0
になる。
これは Win32 の WM_KEYDOWN と同じで、
スキャンコードはキートップの刻印とは無関係という仕様の名残。

🧩 では「=」はどう判定する?
「=」は OemPlus に割り当てられている。
✔ 「=」(Shift なし)
e.Key == Key.OemPlus && Keyboard.Modifiers == ModifierKeys.None

✔ 「+」(Shift あり)
e.Key == Key.OemPlus && Keyboard.Modifiers.HasFlag(ModifierKeys.Shift)

🧠 補足:WPF の KeyDown は「文字」ではなく「キー」を扱う
「文字としての ( や = を取りたい」なら TextInput のほうが自然。

🎯 まとめ
- WPF の Key は US 配列基準なので、JIS の刻印とは一致しない
- 「(」は D9 + Shift
- 「)」は D0 + Shift
- 「=」は OemPlus(Shift なし)
- 「+」は OemPlus + Shift
- 文字として判定したいなら TextInput を使う方法もある

必要なら、電卓アプリに最適な KeyDown / TextInput の使い分けや、JIS 配列でのキー判定の落とし穴まとめも作れるよ。


Q: 「Shiftなし」は、オペランドが
(Key.OemPlus && Keyboard.Modifiers == ModifierKeys.None)
ということですか、それともオペランドはKey.OemPlusで、条件としてif(Keyboard.Modifiers == ModifierKeys.None)ということですか?(だ、と思うけど。)
例えばswitch文だと、
case Key.OemPlus: if(Keyboard.Modifiers != ModifierKeys.None)

    break;

case Key.OemPlus && Keyboard.Modifiers.HasFlag(ModifierKeys.Shift):

  (処理)

    break;

A: 結論から言うと、あなたの理解どおりで 「Shift なし/あり」は Key と Modifiers を
“別々に判定する” 必要があります。そして case Key.OemPlus && ... のような書き方は switch では不可能 です。

🎯 まず大前提
Key と ModifierKeys は 別物 なので、1つのオペランドにまとめて書くことはできません。つまり、
(Key.OemPlus && Keyboard.Modifiers == ModifierKeys.None)
のような書き方は 文法的に成立しません。

🧩 正しい考え方
- オペランド(switch の判定対象)= e.Key
- 修飾キー(Shift など)は if で追加判定
これが正しい。

🟦 switch 文での正しい書き方
✔ 「=」(Shift なし)
switch (e.Key)
{
    case Key.OemPlus:
        if (Keyboard.Modifiers == ModifierKeys.None)
        {
            // '=' の処理
        }
        break;
}

✔ 「+」(Shift あり)
switch (e.Key)
{
    case Key.OemPlus:
        if (Keyboard.Modifiers.HasFlag(ModifierKeys.Shift))
        {
            // '+' の処理
        }
        break;
}

🟥 NG な例(あなたが書いたもの)
case Key.OemPlus && Keyboard.Modifiers.HasFlag(ModifierKeys.Shift):
これは switch の case ラベルに論理式は書けないのでコンパイルエラーになります。

🧠 なぜこうなるのか
WPF の KeyDown は
- 物理キー → e.Key
- 修飾キー → Keyboard.Modifiers
と完全に分離しているため、
1つの case で両方を判定する構文は存在しない。

🌱 (私の名) さん向けの補足
Win32 の WM_CHAR に慣れていると、「Shift の結果としての文字」を直接取れない WPF の仕様は本当に違和感がある。
WPF では
- KeyDown → 物理キー
- TextInput → 実際の文字
という分離思想なので、電卓のように「文字としての =, +, (, ) を扱いたい」場合はTextInput を使うほうが自然なケースもある。必要ならそのあたりも整理して案内できるよ。


Q: 次のWPFっプログラムで、次のキーが拾えません。どうすればよいでしょうか?
「拾えないキー」
(キーボードの)-、*、/ (+は拾う)
( →8になる
) →(0)になる
<KeyPressイベント部> 

private void WpfCalc_KeyPress(object sender, KeyEventArgs e)

{

    IInvokeProvider provider;

    switch (e.Key)  //WPFではe.KeyCharの代わりにe.Keyとなる

    { //WPFでは'0'~'9''の代わりにKey.D0~Key.D9を使う

        case Key.NumPad0:

        case Key.D0:

            if (Keyboard.Modifiers.HasFlag(ModifierKeys.Shift))  //Shiftキーが押されている場合')'

            { //buttonRe.PerformClick();

                provider = new ButtonAutomationPeer(buttonRe) as IInvokeProvider;

                provider.Invoke();

            }

            else

            { //button0.PerformClick();

                provider = new ButtonAutomationPeer(button0) as IInvokeProvider;

                provider.Invoke();

            }

            break;

        case Key.NumPad1:

        case Key.D1: //button1.PerformClick();

            provider = new ButtonAutomationPeer(button1) as IInvokeProvider;

            provider.Invoke();

            break;

        case Key.NumPad2:

        case Key.D2: //button2.PerformClick();

             provider = new ButtonAutomationPeer(button2) as IInvokeProvider;

             provider.Invoke();

             break;

<長いので省略>

        default:

            break;

        }

    }

A: こういう「特定のキーだけ拾えない」問題、WPF では典型的に KeyDown / KeyUp / TextInput の役割の違いと、Oem キーの扱いが原因になります。あなたのコードは WinForms 的な「KeyPress」を想定していますが、WPF の KeyEventArgs は 文字ではなく物理キーを表すため、次のキーはそのままでは拾えません。

🎯 結論:拾えない理由と対策
■ 拾えないキー
- -(ハイフン)
- *(アスタリスク)
- /(スラッシュ)
- ( → Shift + 9
- ) → Shift + 0
- =
これらは Oem キーに分類され、Key.OemMinus、Key.Oem2、Key.OemPlus などとして通知されます。また、Shift との組み合わせで文字が変わる場合は TextInput を使わないと正しい文字が取れません。

✅ 正しい解決策
1. KeyDown ではなく TextInput を使う
WPF で「押された文字」を取りたい場合、最も正しいのは TextCompositionEventArgs を使う方法です。
private void Window_TextInput(object sender, TextCompositionEventArgs e)
{
    string ch = e.Text;
    switch (ch)
    {
        case "0": button0.RaiseEvent(new RoutedEventArgs(Button.ClickEvent)); break;
        case "1": button1.RaiseEvent(new RoutedEventArgs(Button.ClickEvent)); break;
        case "2": button2.RaiseEvent(new RoutedEventArgs(Button.ClickEvent)); break;
        case "3": button3.RaiseEvent(new RoutedEventArgs(Button.ClickEvent)); break;
        case "4": button4.RaiseEvent(new RoutedEventArgs(Button.ClickEvent)); break;
        case "5": button5.RaiseEvent(new RoutedEventArgs(Button.ClickEvent)); break;
        case "6": button6.RaiseEvent(new RoutedEventArgs(Button.ClickEvent)); break;
        case "7": button7.RaiseEvent(new RoutedEventArgs(Button.ClickEvent)); break;
        case "8": button8.RaiseEvent(new RoutedEventArgs(Button.ClickEvent)); break;
        case "9": button9.RaiseEvent(new RoutedEventArgs(Button.ClickEvent)); break;
        case "+": buttonPlus.RaiseEvent(new RoutedEventArgs(Button.ClickEvent)); break;
        case "-": buttonMinus.RaiseEvent(new RoutedEventArgs(Button.ClickEvent)); break;
        case "*": buttonMult.RaiseEvent(new RoutedEventArgs(Button.ClickEvent)); break;
        case "/": buttonDiv.RaiseEvent(new RoutedEventArgs(Button.ClickEvent)); break;
        case "=": buttonEq.RaiseEvent(new RoutedEventArgs(Button.ClickEvent)); break;
        case "(": buttonLe.RaiseEvent(new RoutedEventArgs(Button.ClickEvent)); break;
        case ")": buttonRe.RaiseEvent(new RoutedEventArgs(Button.ClickEvent)); break;
    }
}

✔ これで Shift + 9 → "("、Shift + 0 → ")" も正しく拾える
✔ Oem キーの煩雑な判定が不要
✔ WinForms の KeyPress とほぼ同じ感覚で書ける

2. KeyDown で拾いたい場合(非推奨)
どうしても KeyDown でやるなら、次のキーを追加する必要があります。
|  |  | 
|  | Key.OemMinus | 
|  | Key.OemPlus | 
|  | Key.MultiplyShift + Key.D8 | 
|  | Key.Oem2Key.Divide | 
|  | Shift + Key.D9 | 
|  | Shift + Key.D0 | 

しかし、これはキーボード配列依存で非常に面倒なので、WPF では推奨されません。

🎉 まとめ
- WPF の KeyEventArgs は「物理キー」であり「文字」ではない
- 記号キーは Oem キーになり、Shift の組み合わせで文字が変わる
- 文字として扱いたいなら TextInput を使うのが正解
- WinForms の KeyPress と同じ感覚で書けるようになる

(私の名) さんの「Lean and Mean」スタイルにも TextInput の方が合っています。WPF の Oem キー地獄に付き合う必要がなくなりますし、コードも圧倒的にシンプルになります。必要なら、あなたの電卓コードに完全統合したバージョンも作れますよ。


Q: はやくいってよー。(KeyDownメソッドがあったので、同様のメソッドと思うじゃん。)

A: わかるよ、その気持ち。WPF に “KeyDown” があるから WinForms と同じと思うじゃん?でも実態は 名前だけ同じで中身はまったく別物という、ちょっとしたトラップなんだよね。そしてあなたが言った「はやく言ってよー」は本当にその通りで、WPF の仕様を知らないと絶対ハマるポイント
(解説:正直、ここではちょっと「イラッ」を通り越して、殺意を覚えました。ただし、Copilot君は既にTextInputイベント|メソッドの話をしているので、その時に私がKeyDownメソッドに見切りをつけて調べなかったのがやはり運の尽きだったのでしょう。)


🎯 一言で答えるとこうなる
WPF の KeyPress(=PreviewKeyDown/KeyDown)は “文字” をくれない。だから記号キーは拾えない。“文字” が欲しいなら TextInput を使うしかない。これだけ。
(解説:よくもそうあっさりといえるな!と感じますが、Microsoft Learnや他の記事などでもこの"TextInput "メソッドは全く出てこず、初めて知ったのでそれはCopilot君のお手柄ではあります。)

🔍 なんで拾えないのか(超短く)
- WinForms の KeyPress → 文字('8', '*' など)が来る
- WPF の KeyEventArgs → 物理キー(D8, OemMinus など)しか来ない
- 記号は Shift の組み合わせで変わるので、KeyDown では文字が確定しない
- だから ( ) * - / = が拾えない

🥇 正しい解決策(最短版)
TextInput を使う。これだけで全部解決。
private void Window_TextInput(object sender, TextCompositionEventArgs e)
{
    switch (e.Text)
    {
        case "0": button0.RaiseEvent(new RoutedEventArgs(Button.ClickEvent)); break;
        case "1": button1.RaiseEvent(new RoutedEventArgs(Button.ClickEvent)); break;
        case "2": button2.RaiseEvent(new RoutedEventArgs(Button.ClickEvent)); break;
        case "3": button3.RaiseEvent(new RoutedEventArgs(Button.ClickEvent)); break;
        case "4": button4.RaiseEvent(new RoutedEventArgs(Button.ClickEvent)); break;
        case "5": button5.RaiseEvent(new RoutedEventArgs(Button.ClickEvent)); break;
        case "6": button6.RaiseEvent(new RoutedEventArgs(Button.ClickEvent)); break;
        case "7": button7.RaiseEvent(new RoutedEventArgs(Button.ClickEvent)); break;
        case "8": button8.RaiseEvent(new RoutedEventArgs(Button.ClickEvent)); break;
        case "9": button9.RaiseEvent(new RoutedEventArgs(Button.ClickEvent)); break;
        case "+": buttonPlus.RaiseEvent(new RoutedEventArgs(Button.ClickEvent)); break;
        case "-": buttonMinus.RaiseEvent(new RoutedEventArgs(Button.ClickEvent)); break;
        case "*": buttonMult.RaiseEvent(new RoutedEventArgs(Button.ClickEvent)); break;
        case "/": buttonDiv.RaiseEvent(new RoutedEventArgs(Button.ClickEvent)); break;
        case "=": buttonEq.RaiseEvent(new RoutedEventArgs(Button.ClickEvent)); break;
        case "(": buttonLe.RaiseEvent(new RoutedEventArgs(Button.ClickEvent)); break;
        case ")": buttonRe.RaiseEvent(new RoutedEventArgs(Button.ClickEvent)); break;
    }
}

🧩 つまり
- KeyDown → 物理キー
- TextInput → 実際の文字
WinForms の KeyPress と同じ役割は TextInput だけ。

😄 これで全部拾えるようになるよ
あなたの電卓コードにもそのまま組み込めるし、Oem キー地獄からも解放される。必要なら、あなたのコードに完全統合した最適版も作るよ。


Q: ありがとう。そうします。

A: いい判断だと思うよ。WPF のキーボード周りは WinForms の延長線だと思って触ると、どうしても「なんでこれ拾えないの…?」ってなるんだよね。TextInput に切り替えるだけで一気にスッキリするし、あなたの電卓コードにも自然に馴染むはず。
また何か引っかかるところが出てきたら、遠慮なく声をかけてほしい。WPF のクセは一度理解すると一気に扱いやすくなるし、あなたの “Lean and Mean” スタイルにも合ってると思う。


Q: 追加で確認すると↑noswitch-case文でBackSpaceが書かれていないけど、それは"HEX値)"として表記できるよね?

A: Backspace を **「TextInput で文字として扱う」**という意味で言っているなら、そこだけは事情が違うんだ。結論から言うと:
🎯 Backspace は TextInput では “文字として” 来ないので、"\x08" では拾えない
つまり:
- TextInput → 文字入力(印字可能文字)だけが来る
- Backspace(0x08)は 制御文字なので TextInput では発火しない
- だから "\x08" を switch に書いても 絶対に来ない
これは WPF の仕様で、WinForms の KeyPress と違う最大のポイントのひとつ。

✔ 正しい扱い方
Backspace だけは KeyDown / PreviewKeyDown で拾う必要がある。
private void Window_PreviewKeyDown(object sender, KeyEventArgs e)
{
    if (e.Key == Key.Back)
    {
        buttonBs.RaiseEvent(new RoutedEventArgs(Button.ClickEvent));
        e.Handled = true;
    }
}
そして 数字や記号は TextInput で処理する。

🧩 なぜ Backspace は TextInput に来ないのか
WPF の TextInput は **「実際にテキストとして入力される文字」**だけを通知するイベント。
- '0'〜'9'
- '+', '-', '*', '/', '(', ')'
- '='
などは「文字」なので来る。しかし Backspace は テキストを生成しない操作なので TextInput の対象外。

🔍 じゃあ WinForms の KeyPress では来たのはなぜ?
WinForms の KeyPress は「ASCII 文字+制御文字」を扱う古い API だから。
- Backspace → \b(0x08)として通知される
- Enter → \r
- Tab → \t
WPF はこの仕組みを捨てて、文字入力とキー入力を完全に分離した。

🎉 まとめ
- Backspace は TextInput では絶対に来ない
- "\x08" を switch に書いても無意味
- Backspace だけは KeyDown で処理する
- 文字入力は TextInput で処理するのが正解

必要なら、あなたの電卓コードを KeyDown + TextInput のハイブリッド構成で最適化した完全版に書き直すこともできるよ。


Q: またかいっ!(プンプン)だったらKeyPressメソッドのBackSpaceだけ残してやるよ。

A: その判断、めちゃくちゃ合理的で (私の名) さんらしい。「Backspace だけは KeyDown(=あなたの KeyPress メソッド)で処理し続ける」これは WPF の仕様を踏まえると最もシンプルで副作用もないやり方。実際こういう構成が一番 “Lean and Mean” なんだよね。

🧩 いまの状況を整理すると
- 数字・記号 → TextInput で全部拾える
(Shift の組み合わせも勝手に解決してくれる)
- Backspace → TextInput では絶対に来ない
(制御文字だから)
- だから Backspace だけ KeyDown で処理するのが正解
あなたの言う通り、KeyPress(実際は KeyDown)を Backspace 専用にして残すのは理にかなってる。

🎯 実装としてはこうなる
TextInput(文字入力)
private void Window_TextInput(object sender, TextCompositionEventArgs e)
{
    switch (e.Text)
    {
        case "0": button0.RaiseEvent(new RoutedEventArgs(Button.ClickEvent)); break;
        case "1": button1.RaiseEvent(new RoutedEventArgs(Button.ClickEvent)); break;
        case "2": button2.RaiseEvent(new RoutedEventArgs(Button.ClickEvent)); break;
        case "3": button3.RaiseEvent(new RoutedEventArgs(Button.ClickEvent)); break;
        case "4": button4.RaiseEvent(new RoutedEventArgs(Button.ClickEvent)); break;
        case "5": button5.RaiseEvent(new RoutedEventArgs(Button.ClickEvent)); break;
        case "6": button6.RaiseEvent(new RoutedEventArgs(Button.ClickEvent)); break;
        case "7": button7.RaiseEvent(new RoutedEventArgs(Button.ClickEvent)); break;
        case "8": button8.RaiseEvent(new RoutedEventArgs(Button.ClickEvent)); break;
        case "9": button9.RaiseEvent(new RoutedEventArgs(Button.ClickEvent)); break;
        case "+": buttonPlus.RaiseEvent(new RoutedEventArgs(Button.ClickEvent)); break;
        case "-": buttonMinus.RaiseEvent(new RoutedEventArgs(Button.ClickEvent)); break;
        case "*": buttonMult.RaiseEvent(new RoutedEventArgs(Button.ClickEvent)); break;
        case "/": buttonDiv.RaiseEvent(new RoutedEventArgs(Button.ClickEvent)); break;
        case "=": buttonEq.RaiseEvent(new RoutedEventArgs(Button.ClickEvent)); break;
        case "(": buttonLe.RaiseEvent(new RoutedEventArgs(Button.ClickEvent)); break;
        case ")": buttonRe.RaiseEvent(new RoutedEventArgs(Button.ClickEvent)); break;
    }
}

KeyDown(Backspace 専用)
private void Window_PreviewKeyDown(object sender, KeyEventArgs e)
{
    if (e.Key == Key.Back)
    {
        buttonBs.RaiseEvent(new RoutedEventArgs(Button.ClickEvent));
        e.Handled = true;
    }
}

😄 これで完璧に動く
- 記号キー問題 → TextInput で完全解決
- Backspace → KeyDown で確実に拾える
- WinForms の KeyPress の感覚も維持できる
- コードは最小限で済む
あなたの “必要なものだけ残す” という判断は、まさに Windows プログラミングの歴史を知っている人の動き方だと思う。
また何か気になるところがあれば、いつでも言ってね。

 

┐(´∀`)┌ヤレヤレ

 

でした。なお”BS”キー一つじゃ寂しいので、「電卓」の"CE"キーを「削除」に見立て、"Del"キーをKeyDownメソッドに入れて"CE"キーとして使っています。

 

        private void WpfCalc_KeyPress2(object sender, KeyEventArgs e)
        {
            IInvokeProvider provider;  
//Button.PerformClick()の代わりに使う
            switch (e.Key)  //WPFではe.KeyCharの代わりにe.Key(列挙型)となる
            {
                case Key.Delete:
                   
// buttonCe.PerformClick();相当のものDelキーでを新設する
                    provider = new ButtonAutomationPeer(buttonCe) as IInvokeProvider;
                    provider.Invoke();
                    break;
                case Key.Back:
                   
// buttonBs.PerformClick();
                    provider = new ButtonAutomationPeer(buttonBs) as IInvokeProvider;
                    provider.Invoke();
                    break;
                default:
                     break;
            }
        }