KeyDown Event

// MainWindow.xaml
<Window
    x:Class="WpfApp3.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:local="clr-namespace:WpfApp3"
    xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
    Title="MainWindow"
    KeyDown="Window_KeyDown"
    Width="800"
    Height="450"
    mc:Ignorable="d">
    <StackPanel>
        <TextBox />
    </StackPanel>
</Window>
// MainWindow.xaml.cs
using System.Diagnostics;
using System.Windows;
using System.Windows.Input;

namespace WpfApp3;
public partial class MainWindow : Window
{
    public MainWindow()
    {
        InitializeComponent();
    }

    private void Window_KeyDown(object sender, KeyEventArgs e)
    {
        Debug.WriteLine("");
    }
}

MainWindow์— TextBox๊ฐ€ ์žˆ์Šต๋‹ˆ๋‹ค.

์—ฌ๊ธฐ์— ํฌ์ปค์Šค๋ฅผ ์ฃผ๊ณ  ํ‚ค ์ž…๋ ฅ์„ ํ–ˆ์„๋•Œ

๋‹น์—ฐํžˆ TextBox์— ํ‚ค ์ž…๋ ฅ์ด ๋จผ์ € ๋  ๊ฒƒ์œผ๋กœ ์ƒ๊ฐ ํ–ˆ๋Š”๋ฐ (๋ฒ„๋ธ”๋ง)

์ด์ƒํ•˜๊ฒŒ Window๊ฐ€ ๋จผ์ € KeyDown์„ ๋ฐ›๊ณ  ์žˆ์Šต๋‹ˆ๋‹ค.

์ œ๊ฐ€ ๋ญ˜ ์ž˜ ๋ชป ์ƒ๊ฐ ํ•œ ๊ฑธ๊นŒ์š”?

1๊ฐœ์˜ ์ข‹์•„์š”

๋ณด์—ฌ ์ฃผ์‹  ์ฝ”๋“œ๋กœ ์ด๋ฒคํŠธ ์ฒ˜๋ฆฌ ์ˆœ์„œ๋ฅผ ์•Œ ์ˆ˜ ์žˆ๋‚˜์š”?

TextBox ๋„ KeyDown ์ด๋ฒคํŠธ ํ•ธ๋“ค๋Ÿฌ๋ฅผ ๋“ฑ๋กํ•ด์•ผ ์ˆœ์„œ๋ฅผ ํ™•์ธํ•  ์ˆ˜ ์žˆ์„ ๊ฒƒ ๊ฐ™์€๋ฐ์š”.

2๊ฐœ์˜ ์ข‹์•„์š”

๋„ค ์˜ˆ์ธกํ•  ์ˆ˜๋Š” ์žˆ์Šต๋‹ˆ๋‹ค.

ํ„ฐ๋„๋ง์— ์˜ํ•ด์„œ Preview๊ฐ€ ๋ถ™์€ ์ด๋ฒคํŠธ๋“ค์ด ๋จผ์ € ๋ฐœ์ƒํ•œ ๋’ค Command๊ฐ€ ๋ฐœ์ƒํ•˜๊ณ  ๋ฒ„๋ธ”๋ง์— ์˜ํ•ด์„œ Preview๋ผ๋Š” ์ ‘๋‘์‚ฌ๊ฐ€ ์•ˆ๋ถ™์€ ์ด๋ฒคํŠธ๋“ค์ด ์‹คํ–‰๋˜๋Š”๊ฒŒ WPF์˜ ์ผ๋ฐ˜์ ์ธ ์ด๋ฒคํŠธ ํ˜ธ์ถœ ํ๋ฆ„์ž…๋‹ˆ๋‹ค.

TextBox์— ํฌ์ปค์‹ฑ์ด ๋˜์–ด์žˆ๋‹ค๋ฉด ์ƒ์œ„ ์ปจํŠธ๋กค์ธ Window, Stackpanel์˜ Preview Keydown์„ ๊ฑฐ์ณ์„œ ์‹คํ–‰๋œ ๋’ค, TextBox์˜ Command๊ฐ€ ์‹คํ–‰๋˜๊ณ  (๋ฐ”์ธ๋”ฉ๋œ๊ฒŒ ์žˆ์œผ๋ฉด), ์ดํ›„ TextBox๋ฅผ ์‹œ์ž‘์œผ๋กœ StackPanel, Window ๊นŒ์ง€ ๋ฒ„๋ธ”๋ง์œผ๋กœ ์‹คํ–‰๋˜๊ธฐ ๋•Œ๋ฌธ์—

์ œ ์ƒ๊ฐ๋„ code๋‹˜์˜ ์˜๊ฒฌ์ฒ˜๋Ÿผ TextBox์— ๋จผ์ € Text๊ฐ€ ์ž…๋ ฅ๋œ ํ›„์— ๋ฒ„๋ธ”๋ง์— ์˜ํ•ด Window์— ๋“ฑ๋ก๋œ Keydown์ด ์‹คํ–‰๋˜์–ด์•ผ ๋งž๋Š” ๊ฒƒ ๊ฐ™์€๋ฐโ€ฆ

๊ทธ๋ž˜์„œ ์ €๋„ ์•Œ์•„๋ณด๋Š” ์ค‘์ด๋„ค์š”.

1๊ฐœ์˜ ์ข‹์•„์š”

์šฐ์„  ์ด ๊ธ€์„ ์ฐธ๊ณ ํ–ˆ์Šต๋‹ˆ๋‹ค.

๋ณด๋ฉด ์ด๋Ÿฐ ๋ง์ด ์žˆ๋Š”๋ฐ

ํ‚ค๋ณด๋“œ ์ž…๋ ฅ์˜ ๊ฒฝ์šฐ WPF๋Š” ๋จผ์ € ์ ์ ˆํ•œ KeyDown/KeyUp ์ด๋ฒคํŠธ๋ฅผ ๋ณด๋ƒ…๋‹ˆ๋‹ค. ํ•ด๋‹น ์ด๋ฒคํŠธ๊ฐ€ ์ฒ˜๋ฆฌ๋˜์ง€ ์•Š์•˜์œผ๋ฉฐ ํ‚ค๊ฐ€ ๋ฐฉํ–ฅ ํ™”์‚ดํ‘œ ํ‚ค ๋˜๋Š” ๊ธฐ๋Šฅ ํ‚ค์™€ ๊ฐ™์€ ์ œ์–ด ํ‚ค๊ฐ€ ์•„๋‹ˆ๋ผ ํ…์ŠคํŠธ ํ‚ค์ด๋ฉด TextInput ์ด๋ฒคํŠธ๊ฐ€ ๋ฐœ์ƒํ•ฉ๋‹ˆ๋‹ค. ์—ฌ๋Ÿฌ ํ‚ค์ŠคํŠธ๋กœํฌ๋กœ ๋‹จ์ผ ํ…์ŠคํŠธ ์ž…๋ ฅ ๋ฌธ์ž๋ฅผ ์ƒ์„ฑํ•  ์ˆ˜ ์žˆ๊ณ  ๋‹จ์ผ ํ‚ค์ŠคํŠธ๋กœํฌ๋กœ ๋‹ค์ค‘ ๋ฌธ์ž ๋ฌธ์ž์—ด์„ ์ƒ์„ฑํ•  ์ˆ˜ ์žˆ์œผ๋ฏ€๋กœ KeyDown/KeyUp๊ณผ TextInput ์ด๋ฒคํŠธ ๊ฐ„์— ํ•ญ์ƒ ๋‹จ์ˆœํžˆ ์ผ ๋Œ€ ์ผ ๋งคํ•‘์ด ๊ตฌ์„ฑ๋˜๋Š” ๊ฒƒ์€ ์•„๋‹™๋‹ˆ๋‹ค. ์ด๋Š” ํŠนํžˆ ๊ฐ ์–ธ์–ด์˜ ์•ŒํŒŒ๋ฒณ์œผ๋กœ ์ˆ˜์ฒœ ๊ฐœ์˜ ๊ฐ€๋Šฅํ•œ ๋ฌธ์ž๋ฅผ ์ƒ์„ฑํ•˜๋Š” ๋ฐ IME(์ž…๋ ฅ๊ธฐ)๋ฅผ ์‚ฌ์šฉํ•˜๋Š” ํ•œ๊ตญ์–ด, ์ค‘๊ตญ์–ด ๋ฐ ์ผ๋ณธ์–ด ๋“ฑ์˜ ์–ธ์–ด์—์„œ ๋”์šฑ ๊ทธ๋ ‡์Šต๋‹ˆ๋‹ค.

WPF๊ฐ€ KeyUp/KeyDown ์ด๋ฒคํŠธ๋ฅผ ๋ณด๋‚ด๋ฉด ํ‚ค์ŠคํŠธ๋กœํฌ๊ฐ€ TextInput ์ด๋ฒคํŠธ์˜ ์ผ๋ถ€๊ฐ€ ๋  ์ˆ˜ ์žˆ๋Š” ๊ฒฝ์šฐ(์˜ˆ๋ฅผ ๋“ค์–ด Alt+S๋ฅผ ๋ˆ„๋ฅด๋Š” ๊ฒฝ์šฐ)Key๋Š” Key.System์œผ๋กœ ์„ค์ •๋ฉ๋‹ˆ๋‹ค. ์ด๋ฅผ ํ†ตํ•ด KeyDown ์ด๋ฒคํŠธ ์ฒ˜๋ฆฌ๊ธฐ์˜ ์ฝ”๋“œ๋Š” Key.System์„ ํ™•์ธํ•˜๊ณ , ์ฐพ์€ ๊ฒฝ์šฐ ์ดํ›„์— ๋ฐœ์ƒํ•œ TextInput ์ด๋ฒคํŠธ์— ๋Œ€ํ•œ ์ฒ˜๋ฆฌ๊ธฐ๊ฐ€ ์ฒ˜๋ฆฌ๋˜๋„๋ก ๋‘˜ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์ด๋Ÿฌํ•œ ๊ฒฝ์šฐ TextCompositionEventArgs ์ธ์ˆ˜์˜ ๋‹ค์–‘ํ•œ ์†์„ฑ์„ ์‚ฌ์šฉํ•˜์—ฌ ์›๋ž˜ ํ‚ค์ŠคํŠธ๋กœํฌ๋ฅผ ํ™•์ธํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ๋งˆ์ฐฌ๊ฐ€์ง€๋กœ IME๊ฐ€ ํ™œ์„ฑ ์ƒํƒœ์ธ ๊ฒฝ์šฐ Key๋Š” Key.ImeProcessed ๊ฐ’์„ ๊ฐ€์ง€๋ฉฐ ImeProcessedKey๊ฐ€ ์›๋ž˜ ํ‚ค์ŠคํŠธ๋กœํฌ๋ฅผ ์ œ๊ณตํ•ฉ๋‹ˆ๋‹ค.

๋ฌด์Šจ ๋ง์ธ์ง€ ๊ฐ์ด ์ž˜ ์•ˆ์™€๋‹ฟ์•„์„œ @BigSquare ๋‹˜ ๋ง์”€์ฒ˜๋Ÿผ ๋‹ค์ณ๋ดค์Šต๋‹ˆ๋‹ค.

<Window x:Class="WpfApp1.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:local="clr-namespace:WpfApp1"
        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
        Title="MainWindow"
        Width="800"
        Height="450"
        KeyDown="Window_KeyDown"
        PreviewKeyDown="Window_PreviewKeyDown"
        mc:Ignorable="d">
    <StackPanel KeyDown="StackPanel_KeyDown"
                PreviewKeyDown="StackPanel_PreviewKeyDown">
        <TextBox KeyDown="TextBox_KeyDown"
                 PreviewKeyDown="TextBox_PreviewKeyDown"
                 PreviewTextInput="TextBox_PreviewTextInput"
                 TextInput="TextBox_TextInput" />
    </StackPanel>
</Window>
using System.Diagnostics;
using System.Windows;
using System.Windows.Input;

namespace WpfApp1;

public partial class MainWindow : Window
{
    public MainWindow()
    {
        InitializeComponent();
    }

    private void Window_KeyDown(object sender, KeyEventArgs e)
    {
        Debug.WriteLine("Window_KeyDown");
    }

    private void StackPanel_KeyDown(object sender, KeyEventArgs e)
    {
        Debug.WriteLine("StackPanel_KeyDown");
    }

    private void TextBox_TextInput(object sender, TextCompositionEventArgs e)
    {
        Debug.WriteLine("TextBox_TextInput");
    }

    private void TextBox_KeyDown(object sender, KeyEventArgs e)
    {
        Debug.WriteLine("TextBox_KeyDown");
    }

    private void StackPanel_PreviewKeyDown(object sender, KeyEventArgs e)
    {
        Debug.WriteLine("StackPanel_PreviewKeyDown");
    }

    private void TextBox_PreviewKeyDown(object sender, KeyEventArgs e)
    {
        Debug.WriteLine("TextBox_PreviewKeyDown");
    }

    private void TextBox_PreviewTextInput(object sender, TextCompositionEventArgs e)
    {
        Debug.WriteLine("TextBox_PreviewTextInput");
    }

    private void Window_PreviewKeyDown(object sender, KeyEventArgs e)
    {
        Debug.WriteLine("Window_PreviewKeyDown");
    }
}

๊ทธ๋žฌ๋”๋‹ˆ ์•„๋ž˜์ฒ˜๋Ÿผ ๋‚˜์˜ค๋„ค์š”.

  1. Window_PreviewKeyDown
  2. StackPanel_PreviewKeyDown
  3. TextBox_PreviewKeyDown
  4. TextBox_KeyDown
  5. StackPanel_KeyDown
  6. Window_KeyDown
  7. TextBox_PreviewTextInput

๊ฒฐ๊ณผ๋ฅผ ๋ณด๋‹ˆ Focus๋œ TextBox์— KeyDown์ด ํ„ฐ๋„๋ง๊ณผ ๋ฒ„๋ธ”๋ง์ด ๋ชจ๋‘ ํ˜ธ์ถœ๋œ ๋‹ค์Œ, ์‹ค์ œ๋กœ TextBox์˜ Text๋ฅผ ๋ณ€๊ฒฝํ•ด์ฃผ๋Š” TextInput ๋ฉ”์„œ๋“œ๊ฐ€ ํ˜ธ์ถœ์ด ๋˜๊ณ  ์žˆ๋„ค์š”.
TextInput๊ณผ PreivewTextInput์„ ๋‘˜๋‹ค ๋“ฑ๋กํ•ด์„œ PreviewTextInput์—์„œ ์ฒ˜๋ฆฌ๊ฐ€ ๋˜์–ด, TextInput์ด ๋ฐœ์ƒํ•˜์ง€ ์•Š๋Š” ๊ฒƒ ๊ฐ™์Šต๋‹ˆ๋‹ค.
์‚ฌ์šฉ์ž๊ฐ€ PreviewTextInput์„ ๋“ฑ๋กํ•˜์ง€ ์•Š์•˜๋”๋ผ๋„ WPF FCL ์ž์ฒด์— ๊ธฐ๋ณธ ๊ตฌํ˜„๋œ PreviewTextInput์—์„œ ์ฒ˜๋ฆฌ๊ฐ€ ๋˜์—ˆ์„ ๊บผ๋ผ๊ณ  ์ถ”์ธกโ€ฆ์ค‘์ž…๋‹ˆ๋‹ค. ์–ด๋–ค ๊ฑด์ง€ ๋ชจ๋ฅด๊ฒ ๋Š”๋ฐ ์—„์ฒญ ๋งŽ์ด์žˆ๋„ค์š”

๊ฒฐ๋ก ์€ KeyDown์ด ํ„ฐ๋„๋ง์œผ๋กœ ํƒ€๊ณ  ๋“ค์–ด๊ฐ€์„œ, ํ‚ค๋ณด๋“œ ๋งคํ•‘์—์„œ ์ ์ ˆํ•œ ํ‚ค์ž…๋ ฅ์ด ๋ฐœ๊ฒฌ๋˜๋ฉด ์šฐ์„  ๋ฒ„๋ธ”๋ง KeyDown ๊นŒ์ง€ ๋‹ค ์ฒ˜๋ฆฌํ•˜๊ณ  ๋‚˜์„œ TextInput์— ์˜ํ•ด ํ‚ค๊ฐ€ ์ž…๋ ฅ๋˜๊ณ  ๋ Œ๋”๋ง์ด ๋˜๋Š” ๊ฒƒ ๊ฐ™๋„ค์š”.

๊ทธ๊ฒŒ ์œ„ ๋ฌธ์„œ์˜ ์•„๋ž˜ ๋ง ๊ฐ™์Šต๋‹ˆ๋‹ค.

์ž…๋ ฅ ์ด๋ฒคํŠธ๋Š” ์ด๋ฒคํŠธ ๊ฒฝ๋กœ์˜ ์œ„์ชฝ์œผ๋กœ ๋ฒ„๋ธ”๋งํ•˜๋ฏ€๋กœ StackPanel์€ ์–ด๋–ค ์š”์†Œ์— ํ‚ค๋ณด๋“œ ํฌ์ปค์Šค๊ฐ€ ์žˆ๋Š”์ง€์— ๊ด€๊ณ„์—†์ด ์ž…๋ ฅ์„ ๋ฐ›์Šต๋‹ˆ๋‹ค. TextBox ์ปจํŠธ๋กค์ด ๋จผ์ € ์•Œ๋ฆผ์„ ๋ฐ›์œผ๋ฉฐ OnTextInputKeyDown ์ฒ˜๋ฆฌ๊ธฐ๋Š” TextBox๊ฐ€ ์ž…๋ ฅ์„ ์ฒ˜๋ฆฌํ•˜์ง€ ์•Š์€ ๊ฒฝ์šฐ์—๋งŒ ํ˜ธ์ถœ๋ฉ๋‹ˆ๋‹ค. PreviewKeyDown ์ด๋ฒคํŠธ๊ฐ€ KeyDown ์ด๋ฒคํŠธ ๋Œ€์‹  ์‚ฌ์šฉ๋˜๋ฉด OnTextInputKeyDown ์ฒ˜๋ฆฌ๊ธฐ๊ฐ€ ๋จผ์ € ํ˜ธ์ถœ๋ฉ๋‹ˆ๋‹ค.

2๊ฐœ์˜ ์ข‹์•„์š”

๋งํฌ์˜ ๊ธ€๊ณผ ์ด ์งˆ๋ฌธ์€ ์•ฝ๊ฐ„ ํ•€ํŠธ๊ฐ€ ๋‹ค๋ฆ…๋‹ˆ๋‹ค.

๋ฒ„๋ธ”๋ง๊ณผ ํ„ฐ๋„๋ง์€ ์ด๋ฒคํŠธ ํ•ธ๋“ค๋Ÿฌ ํ˜ธ์ถœ ์ฒด์ธ์— ๊ด€ํ•œ ๊ฒƒ์ด๊ณ , ๋งํฌ์˜ ๊ธ€์€ event spawn - ์ด๋ฒคํŠธ๊ฐ€ ๋‹ค๋ฅธ ์ด๋ฒคํŠธ๋ฅผ raise ํ•˜๋Š” ๊ฒฝ์šฐ๋ฅผ ์„ค๋ช…ํ•˜๋Š” ๊ฒƒ์ž…๋‹ˆ๋‹ค.

์ฆ‰ ์ „์ž๋Š” ํ•˜๋‚˜์˜ ์ด๋ฒคํŠธ ์†Œ์Šค๊ฐ€ ์–ด๋–ป๊ฒŒ ๋ณต์ˆ˜์˜ ํ•ธ๋“ค๋Ÿฌ๋ฅผ ํ˜ธ์ถœํ•˜๋Š” ์ง€์— ๊ด€ํ•œ ๊ฒƒ์ด๊ณ , ํ›„์ž๋Š” ํŠน์ • ์ด๋ฒคํŠธ ์†Œ์Šค ์‚ฌ์ด์˜ ์ƒ๊ด€ ๊ด€๊ณ„๋ฅผ ์„ค๋ช…ํ•˜๋Š” ๊ฒƒ์ž…๋‹ˆ๋‹ค.

TextBox.KeyDown ์ด๋ฒคํŠธ๋Š” ํ•œ ๋ฒˆ๋งŒ ์ผ์–ด๋‚ฉ๋‹ˆ๋‹ค.

์ด ์ด๋ฒคํŠธ์— ์ง์ ‘ ๋“ฑ๋กํ•œ ํ•ธ๋“ค๋Ÿฌ ๋ฟ๋งŒ ์•„๋‹ˆ๋ผ, ์ด ์š”์†Œ์˜ ๋ถ€๋ชจ ์š”์†Œ๋กœ ๊ฑฐ์Šฌ๋กœ ์˜ฌ๋ผ๊ฐ€ ๋™์ผํ•œ ํ•ธ๋“ค๋Ÿฌ๋ฅผ ์—ฐ์†ํ•ด์„œ ํ˜ธ์ถœํ•˜๋Š” ๊ฒƒ์ด ๋ฒ„๋ธ”๋ง์ž…๋‹ˆ๋‹ค.

WPF ๋ฟ๋งŒ ์•„๋‹ˆ๋ผ, Html ์˜ ์ด๋ฒคํŠธ์—๋„ ๋™์ผํ•œ ๊ฐœ๋…์ด ์žˆ์Šต๋‹ˆ๋‹ค.

WPF๋Š” ํŠน์ดํ•˜๊ฒŒ Preview ์ด๋ฒคํŠธ ํ•ธ๋“ค๋Ÿฌ๋ฅผ ์ œ๊ณตํ•ฉ๋‹ˆ๋‹ค.
๋ Œ๋”๋ง ํŠธ๋ฆฌ์˜ ์ตœ ์ƒ๋‹จ์œผ๋กœ๋ถ€ํ„ฐ ์ด๋ฒคํŠธ ์†Œ์Šค ๋ฐฉํ–ฅ์œผ๋กœ ์ด๋ฒคํŠธ ํ•ธ๋“ค๋Ÿฌ๊ฐ€ ํ˜ธ์ถœ๋ฉ๋‹ˆ๋‹ค.(ํ„ฐ๋„๋ง)

๊ทธ๋ž˜์„œ, ํ”„๋ฆฌ๋ทฐ ํ•ธ๋“ค๋Ÿฌ๊ฐ€ ๋จผ์ € ํ˜ธ์ถœ๋˜๊ณ , ๊ทธ ๋‹ค์Œ ์ด๋ฒคํŠธ ํ•ธ๋“ค๋Ÿฌ๊ฐ€ ํ˜ธ์ถœ๋ฉ๋‹ˆ๋‹ค.

2๊ฐœ์˜ ์ข‹์•„์š”

์šฐ์„  ์œ„ ์ฒ˜๋ฆฌ์˜ ๋ชฉ์ ๋ถ€ํ„ฐ ๋ง์”€ ๋“œ๋ฆฌ๋ฉด

์ €ํฌ ํ”„๋กœ๊ทธ๋žจ์€ ๋‚ด๋ถ€์ ์œผ๋กœ ๋‹จ์ถ•ํ‚ค ๊ฐ™์€ ๊ฐœ๋…์ด ์žˆ์Šต๋‹ˆ๋‹ค. (์˜ต์…˜ํ‚ค๋ฅผ ์•ˆ์“ฐ๊ณ  ๊ทธ๋ƒฅ A, S, D ๋“ฑ๋“ฑ)

๊ทธ๋ž˜์„œ ์„ค์ • ๋œ ๋‹จ์ถ•ํ‚ค๋ฅผ ๋ˆ„๋ฅด๋ฉด ๋ฉ”์ธ์œˆ๋„์šฐ์—์„œ ๋ฐ›์•„ ์ฒ˜๋ฆฌ ํ•˜๊ณ  Handled = true ์ฒ˜๋ฆฌ ํ•ฉ๋‹ˆ๋‹ค.

๊ทธ๋ฆฌ๊ณ  ์ฐฝ์— DataGrid๊ฐ€ ์žˆ๋Š”๋ฐ ์—ฌ๊ธฐ์˜ TextColumn ์— ๊ฐ’์„ ์•„๋ฌด๋ฆฌ ์ž…๋ ฅ ํ•˜๋ ค๊ณ  ํ•ด๋„

๋‹จ์ถ•ํ‚ค๊ฐ€ ๋จผ์ € ๋จน์—ˆ์Šต๋‹ˆ๋‹ค.

์ œ๊ฐ€ ์ฐฉ๊ฐ ํ•œ๊ฒƒ์€ TextBox์˜ ์ž…๋ ฅ ์ฒ˜๋ฆฌ๊ฐ€ KeyDown ์ธ์ค„ ์•Œ์•˜์œผ๋‚˜

์œ„์— @Vincent ๋‹˜์ด ๋ง์”€ ํ•˜์‹ ๊ฒƒ ์ฒ˜๋Ÿผ TextBox ๋Š” KeyDown ์„ ์ฒ˜๋ฆฌ ํ•˜์ง€ ์•Š๊ณ 

TextInput์œผ๋กœ ์ฒ˜๋ฆฌ ํ•˜๋Š” ๊ฑธ ์•Œ๊ฒŒ ๋์Šต๋‹ˆ๋‹ค.

๊ทธ๋ž˜์„œ TextBox๊ฐ€ ํฌ์ปค์Šค๊ฐ€ ์žˆ์–ด๋„ TextBox๋Š” KeyDown์„ ์ฒ˜๋ฆฌ ํ•˜์ง€ ์•Š์•„

์œˆ๋„์šฐ๊นŒ์ง€ ๊ฐ€๊ฒŒ ๋œ ๊ฒƒ์ด์—ˆ์Šต๋‹ˆ๋‹ค.

ํ•ด๊ฒฐ ๋ฐฉ๋ฒ•์€ KeyDown ์ด๋ฒคํŠธ์—์„œ OriginalSource ๋ฅผ ์ฒดํฌํ•˜์—ฌ ํƒ€์ž…์ด TextBox ๋ฉด

return ์œผ๋กœ ์ฒ˜๋ฆฌ ํ–ˆ์Šต๋‹ˆ๋‹ค.

๋‘๋ถ„ ๋ชจ๋‘ ๊ฐ์‚ฌํ•ฉ๋‹ˆ๋‹ค.

2๊ฐœ์˜ ์ข‹์•„์š”

๋„ค ๋ง์”€ํ•˜์‹  ๊ฒƒ์ด ๋งž์Šต๋‹ˆ๋‹ค.
์ €๋„ @code ๋‹˜์˜ ์งˆ๋ฌธ์„ ๋ณด๊ณ  ํ„ฐ๋„๋ง๊ณผ ๋ฒ„๋ธ”๋ง์˜ ๊ด€๊ณ„๋กœ๋งŒ ์ ‘๊ทผํ–ˆ๋‹ค๊ฐ€, ์˜ˆ์‹œ์˜ ์ด ๊ธ€์ด TextBox ์˜€๊ธฐ ๋•Œ๋ฌธ์— TextInput ๋•Œ๋ฌธ์— ๊ฒฐ๊ณผ๋ก  ์ ์ธ ํ˜„์ƒ์ด ๋ณด์—ฌ์ง€๋Š” ๊ฑฐ๋ผ์„œ ๋ณตํ•ฉ์ ์ด๊ฒŒ ์„ค๋ช…ํ•œ ๊ฒƒ์ด ๋งž์Šต๋‹ˆ๋‹ค.

๊ทธ๋ฆฌ๊ณ  HTML์—๋„ ๋™์ผํ•˜๊ฒŒ ๋ฒ„๋ธ”๋ง๊ณผ ํ„ฐ๋„๋ง์ด ์žˆ๋Š” ๊ฒƒ์€ ์•Œ๊ณ  ์žˆ์—ˆ๋Š”๋ฐ, Preview ์ด๋ฒคํŠธ ํ•ธ๋“ค๋Ÿฌ๋ฅผ WPF๋งŒ ์ œ๊ณตํ•˜๋Š” ๊ฒƒ์€ ์ฒ˜์Œ ์•Œ์•˜๋„ค์š”.

๊ฐ์‚ฌํ•ฉ๋‹ˆ๋‹ค.

2๊ฐœ์˜ ์ข‹์•„์š”

Html ์—๋Š” ํ„ฐ๋„๋ง์ด ์—†๊ณ , ๋ฒ„๋ธ”๋ง๋งŒ ์žˆ์Šต๋‹ˆ๋‹ค.

2๊ฐœ์˜ ์ข‹์•„์š”

๊ทธ๋žฌ๊ตฐ์š”! ์ฒดํฌ ๊ฐ์‚ฌ๋“œ๋ฆฝ๋‹ˆ๋‹ค.

2๊ฐœ์˜ ์ข‹์•„์š”

์•„๋ž˜์˜ ์š”๊ตฌ ์‚ฌํ•ญ์€ WPF ์—์„œ ์ฒ˜๋ฆฌํ•˜๋Š” ๊ฒŒ ์‰ฝ์ง€ ์•Š์„ ๊ฒƒ์ž…๋‹ˆ๋‹ค.

์™œ๋ƒํ•˜๋ฉด, WPF ์—์„œ๋Š” ํฌ์ปค์Šค๋œ ์š”์†Œ๋งŒ์ด ์ด๋ฒคํŠธ๋ฅผ ์ „ํŒŒํ•  ์ˆ˜ ์žˆ๊ธฐ ๋•Œ๋ฌธ์ž…๋‹ˆ๋‹ค.

์ด๋Ÿฌํ•œ ์ œํ•œ์ด ์žˆ๋Š” ๊ฒฝ์šฐ, ์•„๋ž˜์™€ ๊ฐ™์ด ์ฒ˜๋ฆฌํ•˜๋ฉด, ์ด๋ฒคํŠธ ๊ฐ„ ๊ฐ„์„ญ์€ ์—†์–ด์งˆ์ง€ ๋ชฐ๋ผ๋„, Window ๊ฐ€ ํฌ์ปค์Šค๋ฅผ ๊ฐ€์ง€๊ณ  ์žˆ์ง€ ์•Š์œผ๋ฉด, ๋‹จ์ถ•ํ‚ค ๋กœ์ง์€ ์‹คํ–‰๋  ๊ธฐํšŒ ์ž์ฒด๊ฐ€ ์—†์„ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

Window ๊ฐ€ Loaded ๋œ ํ›„์—๋Š” Window ๊ฐ€ Focus ๋ฅผ ๊ฐ€์งˆ ์ˆ˜๋„ ์žˆ๊ณ  ์•ˆ ๊ฐ€์งˆ ์ˆ˜๋„ ์žˆ์Šต๋‹ˆ๋‹ค.
๊ฐ€์ง„ ๊ฒฝ์šฐ์—๋Š” ๋ฌธ์ œ๊ฐ€ ์—†์ง€๋งŒ, ์•ˆ ๊ฐ€์ง„ ๊ฒฝ์šฐ์—๋Š” ๋‹จ์ถ•ํ‚ค๋Š” ๋™์ž‘ํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค.

๋งŒ์•ฝ TextBox ์— ์ž…๋ ฅ์ด ์™„๋ฃŒ๋œ ํ›„ ํฌ์ปค์Šค๊ฐ€ ๋‹ค์‹œ Window ๋กœ ๋Œ์•„ ๊ฐ€์ง€ ์•Š์œผ๋ฉด ๋‹จ์ถ•ํ‚ค ๋กœ์ง์€ ์‹คํ–‰๋˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค. (์ด๋ฒคํŠธ ํ•ธ๋“ค๋Ÿฌ๋ฅผ ํ˜ธ์ถœํ•  ์ด๋ฒคํŠธ๊ฐ€ ์ „ํŒŒ๋˜๋‹ˆ ์•Š์œผ๋‹ˆ๊นŒ์š”)

์ด์ ์„ ๊ณ ๋ คํ•˜๋Š” ์ฝ”๋“œ๊ฐ€ ์ถ”๊ฐ€๋˜์–ด์•ผ ํ•  ๊ฒƒ ๊ฐ™์Šต๋‹ˆ๋‹ค.

์ € ๊ฐ™์€ ๊ฒฝ์šฐ, ์ „์—ญ ์ด๋ฒคํŠธ๊ฐ€ ์„ค์ •๋œ ๋ทฐ์˜ ํ•˜์œ„ ์š”์†Œ์—์„œ๋Š” ์ด๋ฒคํŠธ ๋ผ์šฐํŒ…(๋ฒ„๋ธ”๋ง)์„ ๋„๋Š” ์„ค์ •์„ ํ•˜๊ณค ํ–ˆ๋Š”๋ฐ, ํ•˜์œ„ ์š”์†Œ๊ฐ€ ๋งŽ์€ ๊ฒฝ์šฐ ์ฝ”๋“œ๊ฐ€ ์กฐ๊ธˆ ๋ฒˆ์žกํ•ด์ง€๋Š” ๋‹จ์ ์ด ์žˆ๋”๊ตฐ์š”.

๊ทธ๋ž˜์„œ ์ „์—ญ ์ด๋ฒคํŠธ ๋ณด๋‹ค๋Š” ๋‹จ์ถ•ํ‚ค ์ „์šฉ ์ž…๋ ฅ ์ฝ˜ํŠธ๋กค์„ ์ •์˜ํ•˜๊ณ ,

<TextBox x:Name="ShortcutCatcher"
         Focusable="True"
         Opacity="0"
         KeyDown="OnShortcutKeyDown"
         IsHitTestVisible="False"
         IsTabStop="False"/>
void OnShortcutKeyDown(object? s, EventArgs e)
{
   // ๋‹จ์ถ•ํ‚ค ์ฒ˜๋ฆฌ
}

// ํฌ์ปค์Šค ๋˜๋Œ๋ฆฌ๊ธฐ ๋กœ์ง 
void SetFocusToShortcutCatcher() =>
   Keyboard.Focus(ShortcutCatcher);

Window Load ์‹œ ์ด ์š”์†Œ์— ํฌ์ปค์Šค๋ฅผ ๊ฐ•์ œํ•˜์—ฌ ๋‹จ์ถ•ํ‚ค๋ฅผ ์ฆ‰์‹œ ๋™์ž‘๊ฐ€๋Šฅํ•œ ์ƒํƒœ๋กœ ๋งŒ๋“ค๊ณ ,

Loaded += (s, e) => SetFocusToShortcutCatcher();

๋ชจ๋“  ํ…์ŠคํŠธ ์ž…๋ ฅ ์š”์†Œ์˜ ์ด๋ฒคํŠธ ์ฒ˜๋ฆฌ ํ›„์—๋Š” ๋ฐ˜๋“œ์‹œ ํฌ์ปค์Šค๋ฅผ ์ด ์š”์†Œ์— ๋˜๋Œ๋ฆฌ๋Š” ์ฒ˜๋ฆฌ๋ฅผ ํ•˜๋Š” ๊ฒƒ์ด ์ข‹์ง€ ์•Š์„๊นŒํ•ฉ๋‹ˆ๋‹ค.

void OnTextInput(object? s, EventArgs e)
{
   // ๊ณ ์œ  ์ด๋ฒคํŠธ ์ฒ˜๋ฆฌ
   SetFocusToShortcutCatcher();
}