안녕하세요. 언제나 휴일에 언휴예요.
이제 앞에서 작성한 두 개의 라이브러리를 참조하여 WPF 번역 나래이터를 만들어 보아요.
화면 배치
제일 먼저 화면 배치를 합니다.

Window의 Content를 Grid로 할게요. Row는 3개, Column은 2개이며 그림처럼 폭과 높이를 설정합시다.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 |
<Window x:Class="번역_나래이터_v0._1.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:번역_나래이터_v0._1" mc:Ignorable="d" Title="번역 나래이터" Height="200" Width="500"> <Grid> <Grid.RowDefinitions> <RowDefinition Height="2*"/> <RowDefinition Height="*"/> <RowDefinition Height="*"/> </Grid.RowDefinitions> <Grid.ColumnDefinitions> <ColumnDefinition Width="5*"/> <ColumnDefinition Width="*"/> </Grid.ColumnDefinitions> <Grid> </Window> |

나머지 부분도 배치합니다. ListBox 내부는 Window의 Load 이벤트 핸들러에서 C# 코드로 직접 작성할 거예요.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 |
<Window x:Class="번역_나래이터_v0._1.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:번역_나래이터_v0._1" mc:Ignorable="d" Loaded="Window_Loaded" Title="번역 나래이터" Height="200" Width="500"> <Grid> <Grid.RowDefinitions> <RowDefinition Height="2*"/> <RowDefinition Height="*"/> <RowDefinition Height="*"/> </Grid.RowDefinitions> <Grid.ColumnDefinitions> <ColumnDefinition Width="5*"/> <ColumnDefinition Width="*"/> </Grid.ColumnDefinitions> <ListBox Name="lbox_narbut"/> <Grid Grid.Row="1"> <Grid.ColumnDefinitions> <ColumnDefinition Width="5*"/> <ColumnDefinition Width="*"/> <ColumnDefinition Width="*"/> </Grid.ColumnDefinitions> <TextBox Name="tbox_src"/> <Button Grid.Column="1" Name="btn_speek" Content="읽기" Click="btn_speek_Click"/> <Button Grid.Column="2" Name="btn_translate" Content="번역" Click="btn_translate_Click"/> </Grid> <Grid Grid.Row="2"> <Grid.ColumnDefinitions> <ColumnDefinition Width="5*"/> <ColumnDefinition Width="2*"/> </Grid.ColumnDefinitions> <Button Grid.Column="1" x:Name="btn_speek2" Content="읽기" Click="btn_speek2_Click"/> <TextBlock x:Name="tbl_trnas"/> </Grid> <Button x:Name="btn_all" IsDefault="True" Click="btn_all_Click" Content="번역/읽기" Grid.RowSpan="3" Grid.Column="1"/> </Grid> </Window> |
MainWindow C# 숨김 코드 작성하기
Load 이벤트 핸드러를 작성합시다.
먼저 Narrator 클래스의 정적 멤버 Narrators 속성에서 나래이터 컬렉션 개체를 얻어옵니다.
1 2 3 4 |
private void Window_Loaded(object sender, RoutedEventArgs e) { List<Narrator> narrators = Narrator.Narrators; } |
그리고 모든 나래이터마다 하나의 Grid 개체를 생성하여 나래이터 정보와 “소개하기” 버튼을 배치할 거예요. 이렇게 생성한 Grid 개체는 ListBox의 Items 컬렉션에 추가합니다.
Xaml에서 표현한 것을 코드로 어떻게 표현하는지 한 번 비교해 보세요. WPF 프로그래밍을 하다보면 코드 숨김 C# 파일에서 이런 작업을 할 때가 발생합니다.
각 UI 요소에 Tag 속성이 있어서 UI 요소와 연관있는 개체를 설정해 두었다가 필요할 때 사용하는 부분도주의 깊게 살펴보세요.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 |
private void Window_Loaded(object sender, RoutedEventArgs e) { List<Narrator> narrators = Narrator.Narrators; Grid grid; ColumnDefinition cd; TextBlock tb_bar; Button button; foreach(Narrator narrator in narrators) { grid = new Grid(); grid.Width = lbox_narbut.ActualWidth - 20; cd = new ColumnDefinition(); cd.Width = new GridLength(5, GridUnitType.Star); grid.ColumnDefinitions.Add(cd); cd = new ColumnDefinition(); cd.Width = new GridLength(1, GridUnitType.Star); grid.ColumnDefinitions.Add(cd); tb_bar = new TextBlock(); tb_bar.Text = narrator.Name; grid.Children.Add(tb_bar); button = new Button(); button.Tag = narrator; button.Content = "소개하기"; button.Click += Button_Click; grid.Children.Add(button); Grid.SetColumn(button, 1); lbox_narbut.Items.Add(grid); grid.Tag = narrator; } } |
나래이터 소개 버튼을 클릭했을 때 처리하는 이벤트 핸들러를 구현합시다. 이벤트 핸들러의 첫 번째 입력 인자는 이벤트 발생을 통보한 개체입니다. 버튼 클릭 이벤트 핸들러에서는 버튼 자신이 sender입니다. 이를 참조 연산하여 사용하는 부분과 Tag에 설정했던 요소를 참조합니다. 그리고 비동기로 자기를 소개합니다.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
private void Button_Click(object sender, RoutedEventArgs e) { Button button = sender as Button; if(button == null) { return; } Narrator narrator = button.Tag as Narrator; if(narrator == null) { return; } narrator.IntroduceAsync(); } |
btn_speek의 클릭 이벤트 핸들러를 작성합시다. 나래이터-버튼 리스트 박스의 첫 번째 아이템 항목에 Grid 개체를 참조합니다.
Grid 개체 Tag 속성에 설정한 Narrator 개체를 참조하여 비동기로 읽어줍니다.
1 2 3 4 5 6 7 8 9 10 |
private void btn_speek_Click(object sender, RoutedEventArgs e) { Grid grid = lbox_narbut.Items[0] as Grid; if(grid == null) { return; } Narrator narrator = grid.Tag as Narrator; narrator.SpeakAsync(tbox_src.Text); } |
btn_translate의 클릭 이벤트 핸들러를 작성합시다. KakaoTranslateAPI 형식의 Translate 정적 메서드를 호출하여 결과를 TextBlock에 표시합니다.
1 2 3 4 5 |
private void btn_translate_Click(object sender, RoutedEventArgs e) { string result = KakaoTransAPI.Translate(tbox_src.Text); tbl_trnas.Text = result; } |
btn_speek2의 클릭 이벤트 핸들러는 btn_speek 이벤트 핸들러와 하는 역할이 같습니다. 차이가 있는 부분은 Narrator 개체입니다.
1 2 3 4 5 6 7 8 9 10 |
private void btn_speek2_Click(object sender, RoutedEventArgs e) { Grid grid = lbox_narbut.Items[1] as Grid; if(grid == null) { return; } Narrator narrator = grid.Tag as Narrator; narrator.SpeakAsync(tbox_src.Text); } |
마지막으로 btn_all의 클릭 이벤트 핸들러를 작성합시다. 위에서 수행한 모든 작업을 수행하게 구현합니다.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 |
private void btn_all_Click(object sender, RoutedEventArgs e) { Grid grid = lbox_narbut.Items[0] as Grid; if(grid == null) { return; } Narrator narrator = grid.Tag as Narrator; narrator.SpeakAsync(tbox_src.Text); string result = KakaoTransAPI.Translate(tbox_src.Text); tbl_trnas.Text = result; grid = lbox_narbut.Items[1] as Grid; if (grid == null) { return; } Narrator narrator2 = grid.Tag as Narrator; narrator2.SpeakAsync(tbox_src.Text); } |
다음은 MainWindow.xaml의 소스 코드입니다.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 |
using System.Collections.Generic; using System.Windows; using System.Windows.Controls; using WrapKakaoLib; using WrapSpeechLib; namespace 번역_나래이터_v0._1 { /// <summary> /// MainWindow.xaml에 대한 상호 작용 논리 /// </summary> public partial class MainWindow : Window { public MainWindow() { InitializeComponent(); } private void btn_speek_Click(object sender, RoutedEventArgs e) { Grid grid = lbox_narbut.Items[0] as Grid; if(grid == null) { return; } Narrator narrator = grid.Tag as Narrator; narrator.SpeakAsync(tbox_src.Text); } private void btn_translate_Click(object sender, RoutedEventArgs e) { string result = KakaoTransAPI.Translate(tbox_src.Text); tbl_trnas.Text = result; } private void btn_speek2_Click(object sender, RoutedEventArgs e) { Grid grid = lbox_narbut.Items[1] as Grid; if(grid == null) { return; } Narrator narrator = grid.Tag as Narrator; narrator.SpeakAsync(tbox_src.Text); } private void btn_all_Click(object sender, RoutedEventArgs e) { Grid grid = lbox_narbut.Items[0] as Grid; if(grid == null) { return; } Narrator narrator = grid.Tag as Narrator; narrator.SpeakAsync(tbox_src.Text); string result = KakaoTransAPI.Translate(tbox_src.Text); tbl_trnas.Text = result; grid = lbox_narbut.Items[1] as Grid; if (grid == null) { return; } Narrator narrator2 = grid.Tag as Narrator; narrator2.SpeakAsync(tbox_src.Text); } private void Window_Loaded(object sender, RoutedEventArgs e) { List<Narrator> narrators = Narrator.Narrators; Grid grid; ColumnDefinition cd; TextBlock tb_bar; Button button; foreach(Narrator narrator in narrators) { grid = new Grid(); grid.Width = lbox_narbut.ActualWidth - 20; cd = new ColumnDefinition(); cd.Width = new GridLength(5, GridUnitType.Star); grid.ColumnDefinitions.Add(cd); cd = new ColumnDefinition(); cd.Width = new GridLength(1, GridUnitType.Star); grid.ColumnDefinitions.Add(cd); tb_bar = new TextBlock(); tb_bar.Text = narrator.Name; grid.Children.Add(tb_bar); button = new Button(); button.Tag = narrator; button.Content = "소개하기"; button.Click += Button_Click; grid.Children.Add(button); Grid.SetColumn(button, 1); lbox_narbut.Items.Add(grid); grid.Tag = narrator; } } private void Button_Click(object sender, RoutedEventArgs e) { Button button = sender as Button; if(button == null) { return; } Narrator narrator = button.Tag as Narrator; if(narrator == null) { return; } narrator.IntroduceAsync(); } } } |
이상으로 Kakao API와 .NET 음성 Speech를 이용한 번역 나래이터 강의를 마칠게요.