チュートリアル:WPF を使って翻訳アプリを作成するTutorial: Create a translation app with WPF

このチュートリアルでは、単一サブスクリプション キーを使ってテキスト翻訳、言語検出、スペル チェックに Azure Cognitive Service API を利用する Windows Presentation Foundation (WPF) アプリを作成します。In this tutorial, you'll build a Windows Presentation Foundation (WPF) app that uses Azure Cognitive Services for text translation, language detection, and spell checking with a single subscription key. 具体的には、アプリから Translator と Bing Spell Check の API を呼び出します。Specifically, your app will call APIs from the Translator and Bing Spell Check.

WPF とはWhat is WPF? デスクトップ クライアント アプリを作成する UI フレームワークです。It's a UI framework that creates desktop client apps. WPF 開発プラットフォームでは、アプリ モデル、リソース、コントロール、グラフィックス、レイアウト、データ バインディング、ドキュメント、セキュリティなど、広範なアプリ開発機能がサポートされています。The WPF development platform supports a broad set of app development features, including an app model, resources, controls, graphics, layout, data binding, documents, and security. .NET Framework のサブセットなので、以前に ASP.NET または Windows フォームを使って .NET Framework でアプリを作成したことがある場合、そのプログラミングの経験を活かすことができます。It's a subset of the .NET Framework, so if you have previously built apps with the .NET Framework using ASP.NET or Windows Forms, the programming experience should be familiar. WPF では、Extensible Application Markup Language (XAML) を使って、アプリ プログラミングの宣言型モデルを提供します。これについては、後のセクションで確認します。WPF uses the Extensible app Markup Language (XAML) to provide a declarative model for app programming, which we'll review in the coming sections.

このチュートリアルで学習する内容は次のとおりです。In this tutorial, you'll learn how to:

  • Visual Studio で WPF プロジェクトを作成するCreate a WPF project in Visual Studio
  • アセンブリと NuGet パッケージをプロジェクトに追加するAdd assemblies and NuGet packages to your project
  • XAML を使用してアプリの UI を作成するCreate your app's UI with XAML
  • Translator を使用して、言語の取得、テキストの翻訳、ソース言語の検出を行うUse the Translator to get languages, translate text, and detect the source language
  • Bing Spell Check API を使用して、入力の検証、翻訳精度の向上を行うUse the Bing Spell Check API to validate your input and improve translation accuracy
  • WPF アプリを実行するRun your WPF app

このチュートリアルで使用する Cognitive ServicesCognitive Services used in this tutorial

この一覧には、このチュートリアルで使用する Cognitive Services が含まれています。This list includes the Cognitive Services used in this tutorial. リンクをたどると、各機能の API リファレンスを閲覧できます。Follow the link to browse the API reference for each feature.

サービスService 機能Feature 説明Description
[変換者]Translator 言語の取得Get Languages テキスト翻訳がサポートされている言語の完全な一覧を取得します。Retrieve a complete list of supported languages for text translation.
[変換者]Translator TranslateTranslate 70 を超す言語にテキストを翻訳できます。Translate text into more than 70 languages.
[変換者]Translator DetectDetect 入力テキストの言語を検出します。Detect the language of the input text. 検出の信頼度スコアが含まれます。Includes confidence score for detection.
Bing Spell CheckBing Spell Check スペル チェックSpell Check スペル ミスを修正して、翻訳精度を向上させます。Correct spelling errors to improve translation accuracy.

前提条件Prerequisites

続行する前に、次が必要です。Before we continue, you'll need the following:

注意

このチュートリアルでは、米国西部リージョンにサブスクリプションを作成することをお勧めします。We recommend creating the subscription in the West US region for this tutorial. それ以外の場合、この演習では、コード内のエンドポイントとリージョンを変更する必要があります。Otherwise, you'll need to change endpoints and regions in the code as you work through this exercise.

Visual Studio で WPF アプリを作成するCreate a WPF app in Visual Studio

最初に実行する必要があるのは、Visual Studio で自分のプロジェクトを設定することです。The first thing we need to do is set up our project in Visual Studio.

  1. Visual Studio を開きます。Open Visual Studio. [新しいプロジェクトの作成] を選択します。Select Create a new project.
  2. [新しいプロジェクトの作成] で、 [WPF アプリ (.NET Framework)] を見つけて選択します。In Create a new project, locate and select WPF App (.NET Framework). [言語] から [C#] を選択して、オプションを絞り込むことができます。You can select C# from Language to narrow the options.
  3. [次へ] を選択し、プロジェクトに MSTranslatorDemo という名前を付けます。Select Next, and then name your project MSTranslatorDemo.
  4. フレームワークのバージョンを .NET Framework 4.7.2 以降に設定し、 [作成] を選択します。Set the framework version to .NET Framework 4.7.2 or later, and select Create. Visual Studio で名前とフレームワークのバージョンを入力するEnter the name and framework version in Visual Studio

プロジェクトが作成されます。Your project has been created. 2 つのタブに MainWindow.xamlMainWindow.xaml.cs が開いていることに注目してください。You'll notice that there are two tabs open: MainWindow.xaml and MainWindow.xaml.cs. このチュートリアルでは、これら 2 つのファイルにコードを追加していきます。Throughout this tutorial, we'll be adding code to these two files. ここでは、アプリのユーザー インターフェイス用の MainWindow.xaml を変更します。We'll modify MainWindow.xaml for the app's user interface. Translator と Bing Spell Check の呼び出し用に MainWindow.xaml.cs を変更します。We'll modify MainWindow.xaml.cs for our calls to Translator and Bing Spell Check. 環境を確認するReview your environment

次のセクションでは、JSON 解析などの追加機能のために、アセンブリと NuGet パッケージをプロジェクトに追加します。In the next section, we're going to add assemblies and a NuGet package to our project for additional functionality, like JSON parsing.

参照と NuGet パッケージをプロジェクトに追加するAdd references and NuGet packages to your project

このプロジェクトには、いくつかの .NET Framework アセンブリと NewtonSoft.Json が必要です。これらは、NuGet パッケージ マネージャーを使用してインストールします。Our project requires a handful of .NET Framework assemblies and NewtonSoft.Json, which we'll install using the NuGet package manager.

.NET Framework アセンブリを追加するAdd .NET Framework assemblies

オブジェクトのシリアル化と逆シリアル化を行うためのアセンブリ、および HTTP 要求と応答を管理するためのアセンブリをプロジェクトに追加します。Let's add assemblies to our project to serialize and deserialize objects, and to manage HTTP requests and responses.

  1. Visual Studio のソリューション エクスプローラーで、自分のプロジェクトを見つけます。Locate your project in Visual Studio's Solution Explorer. 自分のプロジェクトを右クリックし、 [追加] > [参照] の順に選択して、 [参照マネージャー] を開きます。Right-click your project, then select Add > Reference, which opens Reference Manager.
  2. [アセンブリ] タブには、参照に使用できるすべての .NET Framework アセンブリが表示されます。The Assemblies tab lists all .NET Framework assemblies that are available to reference. 右上の検索バーを使用して、参照を検索します。Use the search bar in the upper right to search for references. アセンブリ参照を追加するAdd assembly references
  3. プロジェクトに対して次の参照を選択します。Select the following references for your project:
  4. これらの参照をプロジェクトに追加したら、 [OK] をクリックして、 [参照マネージャー] を閉じることができます。After you've added these references to your project, you can click OK to close Reference Manager.

注意

アセンブリ参照の詳細については、「方法:参照マネージャーを使用して参照を追加または削除する」を参照してください。If you'd like to learn more about assembly references, see How to: Add or remove reference using the Reference Manager.

NewtonSoft.Json をインストールするInstall NewtonSoft.Json

このアプリでは、NewtonSoft.Json を使用して、JSON オブジェクトを逆シリアル化します。Our app will use NewtonSoft.Json to deserialize JSON objects. 次の手順に従ってパッケージをインストールします。Follow these instructions to install the package.

  1. Visual Studio のソリューション エクスプローラーで自分のプロジェクトを見つけて右クリックします。Locate your project in Visual Studio's Solution Explorer and right-click on your project. [NuGet パッケージの管理] を選択します。Select Manage NuGet Packages.

  2. [参照] タブを見つけて選択します。Locate and select the Browse tab.

  3. 検索バーに「NewtonSoft.Json」と入力します。Enter NewtonSoft.Json into the search bar.

    NewtonSoft.Json を見つけてインストールする

  4. パッケージを選択し、 [インストール] をクリックします。Select the package and click Install.

  5. インストールが完了したら、タブを閉じます。When the installation is complete, close the tab.

XAML を使用して WPF フォームを作成するCreate a WPF form using XAML

このアプリを使用するためには、ユーザー インターフェイスが必要です。To use your app, you're going to need a user interface. ユーザーが入力言語と翻訳言語の選択および翻訳するテキストの入力を行うことができ、翻訳の出力を表示するフォームを XAML を使用して作成します。Using XAML, we'll create a form that allows users to select input and translation languages, enter text to translate, and displays the translation output.

作成するものを見てみましょう。Let's take a look at what we're building.

WPF XAML ユーザー インターフェイス

このユーザー インターフェイスには、次のコンポーネントが含まれています。The user interface includes these components:

名前Name TypeType 説明Description
FromLanguageComboBox コンボ ボックスComboBox Microsoft Translator でサポートされているテキスト翻訳の言語の一覧を表示します。Displays a list of the languages supported by Microsoft Translator for text translation. ユーザーは、翻訳前の言語を選択します。The user selects the language they are translating from.
ToLanguageComboBox コンボ ボックスComboBox FromComboBox と同じ言語の一覧を表示しますが、ユーザーの翻訳先の言語を選択するために使用されます。Displays the same list of languages as FromComboBox, but is used to select the language the user is translating to.
TextToTranslate TextBoxTextBox ユーザーが翻訳対象のテキストを入力できます。Allows the user to enter text to be translated.
TranslateButton ボタンButton このボタンを使用して、テキストを翻訳します。Use this button to translate text.
TranslatedTextLabel LabelLabel 翻訳を表示します。Displays the translation.
DetectedLanguageLabel LabelLabel 翻訳するテキスト (TextToTranslate) の検出された言語を表示します。Displays the detected language of the text to be translated (TextToTranslate).

注意

このフォームは XAML ソース コードを使用して作成しますが、Visual Studio のエディターを使用して作成できます。We're creating this form using the XAML source code, however, you can create the form with the editor in Visual Studio.

プロジェクトにコードを追加します。Let's add the code to our project.

  1. Visual Studio で、MainWindow.xaml のタブを選択します。In Visual Studio, select the tab for MainWindow.xaml.
  2. このコードをプロジェクトにコピーし、 [ファイル] > [Save MainWindow.xaml](MainWindow.xaml を上書き保存) を選択して、変更を保存します。Copy this code into your project, and then select File > Save MainWindow.xaml to save your changes.
    <Window x:Class="MSTranslatorDemo.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:MSTranslatorDemo"
            mc:Ignorable="d"
            Title="Microsoft Translator" Height="400" Width="700" BorderThickness="0">
        <Grid>
            <Label x:Name="label" Content="Microsoft Translator" HorizontalAlignment="Left" Margin="39,6,0,0" VerticalAlignment="Top" Height="49" FontSize="26.667"/>
            <TextBox x:Name="TextToTranslate" HorizontalAlignment="Left" Height="23" Margin="42,160,0,0" TextWrapping="Wrap" VerticalAlignment="Top" Width="600" FontSize="14" TabIndex="3"/>
            <Label x:Name="EnterTextLabel" Content="Text to translate:" HorizontalAlignment="Left" Margin="40,129,0,0" VerticalAlignment="Top" FontSize="14"/>
            <Label x:Name="toLabel" Content="Translate to:" HorizontalAlignment="Left" Margin="304,58,0,0" VerticalAlignment="Top" FontSize="14"/>
    
            <Button x:Name="TranslateButton" Content="Translate" HorizontalAlignment="Left" Margin="39,206,0,0" VerticalAlignment="Top" Width="114" Height="31" Click="TranslateButton_Click" FontSize="14" TabIndex="4" IsDefault="True"/>
            <ComboBox x:Name="ToLanguageComboBox"
                    HorizontalAlignment="Left"
                    Margin="306,88,0,0"
                    VerticalAlignment="Top"
                    Width="175" FontSize="14" TabIndex="2">
    
            </ComboBox>
            <Label x:Name="fromLabel" Content="Translate from:" HorizontalAlignment="Left" Margin="40,58,0,0" VerticalAlignment="Top" FontSize="14"/>
            <ComboBox x:Name="FromLanguageComboBox"
                HorizontalAlignment="Left"
                Margin="42,88,0,0"
                VerticalAlignment="Top"
                Width="175" FontSize="14" TabIndex="1"/>
            <Label x:Name="TranslatedTextLabel" Content="Translation is displayed here." HorizontalAlignment="Left" Margin="39,255,0,0" VerticalAlignment="Top" Width="620" FontSize="14" Height="85" BorderThickness="0"/>
            <Label x:Name="DetectedLanguageLabel" Content="Autodetected language is displayed here." HorizontalAlignment="Left" Margin="39,288,0,0" VerticalAlignment="Top" Width="620" FontSize="14" Height="84" BorderThickness="0"/>
        </Grid>
    </Window>
    

Visual Studio に、アプリのユーザー インターフェイスのプレビューが表示されます。You should now see a preview of the app's user interface in Visual Studio. 上の画像のようになります。It should look similar to the image above.

これで、フォームが準備できました。That's it, your form is ready. 次は、Text Translation と Bing Spell Check を使用するためのコードを書きます。Now let's write some code to use Text Translation and Bing Spell Check.

注意

このフォームを自由に調整したり、独自に作成したりできます。Feel free to tweak this form or create your own.

アプリを作成するCreate your app

MainWindow.xaml.cs には、アプリを制御するコードが含まれています。MainWindow.xaml.cs contains the code that controls our app. この後のセクションでは、ドロップダウン メニューを設定するコード、および Translator と Bing Spell Check によって公開されるいくつかの API を呼び出すコードを追加します。In the next few sections, we're going to add code to populate our drop-down menus, and to call a handful of API exposed by Translator and Bing Spell Check.

  • このプログラムが開始され、MainWindow がインスタンス化されると、Translator の Languages メソッドが呼び出されて、言語が取得され、言語選択ドロップダウンが設定されます。When the program starts and MainWindow is instantiated, the Languages method of the Translator is called to retrieve and populate our language selection drop-downs. これは、各セッションの開始時に 1 回行われます。This happens once at the beginning of each session.
  • [Translate] ボタンがクリックされると、ユーザーの言語選択とテキストが取得され、入力に対してスペル チェックが実行され、翻訳と検出された言語がユーザーに表示されます。When the Translate button is clicked, the user's language selection and text are retrieved, spell check is performed on the input, and the translation and detected language are displayed for the user.
    • Translator の Translate メソッドが呼び出されて、TextToTranslate のテキストが翻訳されます。The Translate method of the Translator is called to translate text from TextToTranslate. この呼び出しには、ドロップダウン メニューを使用して選択された tofrom の言語も含まれます。This call also includes the to and from languages selected using the drop-down menus.
    • Translator の Detect メソッドが呼び出されて、TextToTranslate のテキスト言語が判断されます。The Detect method of the Translator is called to determine the text language of TextToTranslate.
    • Bing Spell Check を使用して、TextToTranslate が検証され、スペル ミスが修正されます。Bing Spell Check is used to validate TextToTranslate and adjust misspellings.

このプロジェクトのすべては、MainWindow : Window クラスにカプセル化されます。All of our project is encapsulated in the MainWindow : Window class. まず、サブスクリプション キーを設定し、Translator と Bing Spell Check のエンドポイントを宣言して、アプリを初期化するコードを追加します。Let's start by adding code to set your subscription key, declare endpoints for Translator and Bing Spell Check, and initialize the app.

  1. Visual Studio で、MainWindow.xaml.cs のタブを選択します。In Visual Studio, select the tab for MainWindow.xaml.cs.
  2. 事前に設定された using ステートメントを次に置き換えます。Replace the pre-populated using statements with the following.
    using System;
    using System.Windows;
    using System.Net;
    using System.Net.Http;
    using System.IO;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using Newtonsoft.Json;
    
  3. MainWindow : Window クラスを見つけ、次のコードに置き換えます。Locate the MainWindow : Window class, and replace it with this code:
    {
        // This sample uses the Cognitive Services subscription key for all services. To learn more about
        // authentication options, see: https://docs.microsoft.com/azure/cognitive-services/authentication.
        const string COGNITIVE_SERVICES_KEY = "YOUR_COG_SERVICES_KEY";
        // Endpoints for Translator and Bing Spell Check
        public static readonly string TEXT_TRANSLATION_API_ENDPOINT = "https://api.cognitive.microsofttranslator.com/{0}?api-version=3.0";
        const string BING_SPELL_CHECK_API_ENDPOINT = "https://westus.api.cognitive.microsoft.com/bing/v7.0/spellcheck/";
        // An array of language codes
        private string[] languageCodes;
    
        // Dictionary to map language codes from friendly name (sorted case-insensitively on language name)
        private SortedDictionary<string, string> languageCodesAndTitles =
            new SortedDictionary<string, string>(Comparer<string>.Create((a, b) => string.Compare(a, b, true)));
    
        // Global exception handler to display error message and exit
        private static void HandleExceptions(object sender, UnhandledExceptionEventArgs args)
        {
            Exception e = (Exception)args.ExceptionObject;
            MessageBox.Show("Caught " + e.Message, "Error", MessageBoxButton.OK, MessageBoxImage.Error);
            System.Windows.Application.Current.Shutdown();
        }
        // MainWindow constructor
        public MainWindow()
        {
            // Display a message if unexpected error is encountered
            AppDomain.CurrentDomain.UnhandledException += new UnhandledExceptionEventHandler(HandleExceptions);
    
            if (COGNITIVE_SERVICES_KEY.Length != 32)
            {
                MessageBox.Show("One or more invalid API subscription keys.\n\n" +
                    "Put your keys in the *_API_SUBSCRIPTION_KEY variables in MainWindow.xaml.cs.",
                    "Invalid Subscription Key(s)", MessageBoxButton.OK, MessageBoxImage.Error);
                System.Windows.Application.Current.Shutdown();
            }
            else
            {
                // Start GUI
                InitializeComponent();
                // Get languages for drop-downs
                GetLanguagesForTranslate();
                // Populate drop-downs with values from GetLanguagesForTranslate
                PopulateLanguageMenus();
            }
        }
    // NOTE:
    // In the following sections, we'll add code below this.
    }
    
  4. 自分の Cognitive Services サブスクリプション キーを追加し、保存します。Add your Cognitive Services subscription key and save.

このコード ブロックでは、翻訳可能な言語に関する情報を含む 2 つのメンバー変数を宣言しました。In this code block, we've declared two member variables that contain information about available languages for translation:

変数Variable TypeType 説明Description
languageCodes 文字列の配列Array of strings 言語コードをキャッシュします。Caches the language codes. この Translator サービスは、英語には en というように短いコードを使用して言語を識別します。The Translator service uses short codes, such as en for English, to identify languages.
languageCodesAndTitles 並べ替え済みディクショナリSorted dictionary ユーザー インターフェイス内の「わかりやすい」名前を API で使用される短いコードにマッピングします。Maps the "friendly" names in the user interface back to the short codes used in the API. 大文字と小文字を区別せずアルファベット順の並べ替えを保持します。Kept sorted alphabetically without regard for case.

次に、MainWindow コンストラクター内に、HandleExceptions を使用したエラー処理を追加しました。Then, within the MainWindow constructor, we've added error handling with HandleExceptions. このエラー処理により、例外が処理されない場合にアラートが提供されます。This error handling ensures that an alert is provided if an exception isn't handled. その後、指定されたサブスクリプション キーの長さが 32 文字であることを確認するチェックが実行されます。Then a check is run to confirm the subscription key provided is 32 characters in length. キーが 32 文字よりも短いまたは長い場合、エラーがスローされます。An error is thrown if the key is less than/greater than 32 characters.

少なくともキーの長さが正しい場合、InitializeComponent() が呼び出され、メイン アプリ ウィンドウの XAML 記述の検索、読み込み、およびインスタンス化が行われて、ユーザー インターフェイスが起動します。If there are keys that are at least the right length, the InitializeComponent() call gets the user interface rolling by locating, loading, and instantiating the XAML description of the main app window.

最後に、翻訳の言語を取得するメソッドと、アプリのユーザー インターフェイスのドロップダウン メニューを設定するメソッドを呼び出すコードを追加しました。Last, we've added code to call methods to retrieve languages for translation and to populate the drop-down menus for our app's user interface. ご安心ください。すぐにこれらの呼び出しの背後にあるコードについて説明します。Don't worry, we'll get to the code behind these calls soon.

サポートされている言語を取得するGet supported languages

Translator では、現在、70 を超える言語がサポートされています。The Translator currently supports more than 70 languages. 今後も新しい言語のサポートが追加される予定なので、作成するアプリでは、言語の一覧をハードコーディングせずに、Translator によって公開される Languages リソースを呼び出すことをお勧めします。Since new language support will be added over time, we recommend calling the Languages resource exposed by the Translator rather than hardcoding the language list in your app.

このセクションでは、翻訳可能な言語の一覧が必要であることを指定した、Languages リソースへの GET 要求を作成します。In this section, we'll create a GET request to the Languages resource, specifying that we want a list of languages available for translation.

注意

Languages リソースでは、クエリ パラメーター (transliteration、dictionary、translation) を使用して言語のサポートをフィルター処理できます。The Languages resource allows you to filter language support with the following query parameters: transliteration, dictionary, and translation. 詳細については、API リファレンスに関するページを参照してください。For more information, see API reference.

先に進む前に、Languages リソースへの呼び出しのサンプル出力を確認してみましょう。Before we go any further, let's take a look at a sample output for a call to the Languages resource:

{
  "translation": {
    "af": {
      "name": "Afrikaans",
      "nativeName": "Afrikaans",
      "dir": "ltr"
    },
    "ar": {
      "name": "Arabic",
      "nativeName": "العربية",
      "dir": "rtl"
    }
    // Additional languages are provided in the full JSON output.
}

この出力から、特定の言語の言語コードと name を抽出できます。From this output, we can extract the language code and the name of a specific language. このアプリでは、NewtonSoft.Json を使用して、JSON オブジェクトを逆シリアル化します (JsonConvert.DeserializeObject)。Our app uses NewtonSoft.Json to deserialize the JSON object (JsonConvert.DeserializeObject).

前のセクションの続きから再開し、サポートされている言語をアプリに渡すメソッドを追加します。Picking up where we left off in the last section, let's add a method to get supported languages to our app.

  1. Visual Studio で、MainWindow.xaml.cs のタブを開きます。In Visual Studio, open the tab for MainWindow.xaml.cs.
  2. 次のコードをプロジェクトに追加します。Add this code to your project:
    // ***** GET TRANSLATABLE LANGUAGE CODES
    private void GetLanguagesForTranslate()
    {
        // Send request to get supported language codes
        string uri = String.Format(TEXT_TRANSLATION_API_ENDPOINT, "languages") + "&scope=translation";
        WebRequest WebRequest = WebRequest.Create(uri);
        WebRequest.Headers.Add("Accept-Language", "en");
        WebResponse response = null;
        // Read and parse the JSON response
        response = WebRequest.GetResponse();
        using (var reader = new StreamReader(response.GetResponseStream(), UnicodeEncoding.UTF8))
        {
            var result = JsonConvert.DeserializeObject<Dictionary<string, Dictionary<string, Dictionary<string, string>>>>(reader.ReadToEnd());
            var languages = result["translation"];
    
            languageCodes = languages.Keys.ToArray();
            foreach (var kv in languages)
            {
                languageCodesAndTitles.Add(kv.Value["name"], kv.Key);
            }
        }
    }
    // NOTE:
    // In the following sections, we'll add code below this.
    

GetLanguagesForTranslate() メソッドにより、HTTP GET 要求が作成されます。要求の範囲を翻訳がサポートされている言語に制限するために、scope=translation クエリ文字列パラメーターが使用されています。The GetLanguagesForTranslate() method creates an HTTP GET request, and uses the scope=translation query string parameter is used to limit the scope of the request to supported languages for translation. サポートされている言語は英語で返されるため、en の値を持つ Accept-Language ヘッダーが追加されます。The Accept-Language header with the value en is added so that the supported languages are returned in English.

JSON 応答が解析され、ディクショナリに変換されます。The JSON response is parsed and converted to a dictionary. 次に、言語コードが languageCodes メンバー変数に追加されます。Then the language codes are added to the languageCodes member variable. 言語コードとわかりやすい言語名を含んだキーと値のペアがループ処理され、languageCodesAndTitles メンバー変数に追加されますThe key/value pairs that contain the language codes and the friendly language names are looped through and added to the languageCodesAndTitles member variable. フォームのドロップダウン メニューには、わかりやすい名前が表示されますが、翻訳を要求するにはコードが必要です。The drop-down menus in the form display the friendly names, but the codes are needed to request the translation.

言語ドロップダウン メニューを設定するPopulate language drop-down menus

このユーザー インターフェイスは XAML を使用して定義されているので、InitializeComponent() を呼び出す以外は設定するために行う必要のあることはあまりありません。The user interface is defined using XAML, so you don't need to do much to set it up besides call InitializeComponent(). 行う必要のある 1 つの作業は、 [Translate from] および [Translate to] のドロップダウン メニューにわかりやすい言語名を追加することです。The one thing you need to do is add the friendly language names to the Translate from and Translate to drop-down menus. PopulateLanguageMenus() メソッドを使用して、名前を追加します。The PopulateLanguageMenus() method adds the names.

  1. Visual Studio で、MainWindow.xaml.cs のタブを開きます。In Visual Studio, open the tab for MainWindow.xaml.cs.
  2. 次のコードをプロジェクト内の GetLanguagesForTranslate() メソッドの下に追加します。Add this code to your project below the GetLanguagesForTranslate() method:
    private void PopulateLanguageMenus()
    {
        // Add option to automatically detect the source language
        FromLanguageComboBox.Items.Add("Detect");
    
        int count = languageCodesAndTitles.Count;
        foreach (string menuItem in languageCodesAndTitles.Keys)
        {
            FromLanguageComboBox.Items.Add(menuItem);
            ToLanguageComboBox.Items.Add(menuItem);
        }
    
        // Set default languages
        FromLanguageComboBox.SelectedItem = "Detect";
        ToLanguageComboBox.SelectedItem = "English";
    }
    // NOTE:
    // In the following sections, we'll add code below this.
    

このメソッドにより、languageCodesAndTitles ディクショナリが反復処理され、各キーが両方のメニューに追加されます。This method iterates over the languageCodesAndTitles dictionary and adds each key to both menus. メニューが設定されると、既定の翻訳元言語と翻訳先言語がそれぞれ [Detect][English] に設定されます。After the menus are populated, the default from and to languages are set to Detect and English respectively.

ヒント

メニューの既定の選択肢を設定しない場合、ユーザーは、"to" や "from" の言語を最初に選択せずに [翻訳] をクリックできます。Without a default selection for the menus, the user can click Translate without first choosing a "to" or "from" language. 既定値を使用すれば、この問題を扱う必要がなくなります。The defaults eliminate the need to deal with this problem.

MainWindow が初期化され、ユーザー インターフェイスが作成されたので、ユーザーが [Translate] ボタンをクリックするまでこのコードは実行されません。Now that MainWindow has been initialized and the user interface created, this code won't run until the Translate button is clicked.

ソース テキストの言語を検出するDetect language of source text

Translator を使用して、ソース テキスト (テキスト領域に入力されたテキスト) の言語を検出するメソッドを作成します。Now we're going to create method to detect the language of the source text (text entered into our text area) using the Translator. この要求によって返される値は、後で翻訳要求で使用します。The value returned by this request will be used in our translation request later.

  1. Visual Studio で、MainWindow.xaml.cs のタブを開きます。In Visual Studio, open the tab for MainWindow.xaml.cs.
  2. 次のコードをプロジェクト内の PopulateLanguageMenus() メソッドの下に追加します。Add this code to your project below the PopulateLanguageMenus() method:
    // ***** DETECT LANGUAGE OF TEXT TO BE TRANSLATED
    private string DetectLanguage(string text)
    {
        string detectUri = string.Format(TEXT_TRANSLATION_API_ENDPOINT ,"detect");
    
        // Create request to Detect languages with Translator
        HttpWebRequest detectLanguageWebRequest = (HttpWebRequest)WebRequest.Create(detectUri);
        detectLanguageWebRequest.Headers.Add("Ocp-Apim-Subscription-Key", COGNITIVE_SERVICES_KEY);
        detectLanguageWebRequest.Headers.Add("Ocp-Apim-Subscription-Region", "westus");
        detectLanguageWebRequest.ContentType = "application/json; charset=utf-8";
        detectLanguageWebRequest.Method = "POST";
    
        // Send request
        var serializer = new System.Web.Script.Serialization.JavaScriptSerializer();
        string jsonText = serializer.Serialize(text);
    
        string body = "[{ \"Text\": " + jsonText + " }]";
        byte[] data = Encoding.UTF8.GetBytes(body);
    
        detectLanguageWebRequest.ContentLength = data.Length;
    
        using (var requestStream = detectLanguageWebRequest.GetRequestStream())
            requestStream.Write(data, 0, data.Length);
    
        HttpWebResponse response = (HttpWebResponse)detectLanguageWebRequest.GetResponse();
    
        // Read and parse JSON response
        var responseStream = response.GetResponseStream();
        var jsonString = new StreamReader(responseStream, Encoding.GetEncoding("utf-8")).ReadToEnd();
        dynamic jsonResponse = serializer.DeserializeObject(jsonString);
    
        // Fish out the detected language code
        var languageInfo = jsonResponse[0];
        if (languageInfo["score"] > (decimal)0.5)
        {
            DetectedLanguageLabel.Content = languageInfo["language"];
            return languageInfo["language"];
        }
        else
            return "Unable to confidently detect input language.";
    }
    // NOTE:
    // In the following sections, we'll add code below this.
    

このメソッドにより、Detect リソースへの HTTP POST 要求が作成されます。This method creates an HTTP POST request to the Detect resource. 1 つの引数 text を受け取ります。この引数は要求の本文として渡されます。It takes a single argument, text, which is passed along as the body of the request. 後で、翻訳要求を作成するときに、UI に入力されたテキストが、言語検出のためにこのメソッドに渡されます。Later, we when we create our translation request, the text entered into our UI will be passed to this method for language detection.

さらに、このメソッドでは、応答の信頼度スコアが評価されます。Additionally, this method evaluates the confidence score of the response. スコアが 0.5 より大きい場合、検出された言語がユーザー インターフェイスに表示されます。If the score is greater than 0.5, then the detected language is displayed in our user interface.

ソース テキストのスペル チェックを実行するSpell check the source text

Bing Spell Check API を使用して、ソース テキストのスペル チェックを実行するメソッドを作成します。Now we're going to create a method to spell check our source text using the Bing Spell Check API. スペル チェックを行うことにより、Translator から正確な翻訳が返されることが保証されます。Spell checking ensures that we'll get back accurate translations from the Translator. [Translate] ボタンをクリックすると、翻訳要求でソース テキストへの修正が渡されます。Any corrections to the source text are passed along in our translation request when the Translate button is clicked.

  1. Visual Studio で、MainWindow.xaml.cs のタブを開きます。In Visual Studio, open the tab for MainWindow.xaml.cs.
  2. 次のコードをプロジェクト内の DetectLanguage() メソッドの下に追加します。Add this code to your project below the DetectLanguage() method:
// ***** CORRECT SPELLING OF TEXT TO BE TRANSLATED
private string CorrectSpelling(string text)
{
    string uri = BING_SPELL_CHECK_API_ENDPOINT + "?mode=spell&mkt=en-US";

    // Create a request to Bing Spell Check API
    HttpWebRequest spellCheckWebRequest = (HttpWebRequest)WebRequest.Create(uri);
    spellCheckWebRequest.Headers.Add("Ocp-Apim-Subscription-Key", COGNITIVE_SERVICES_KEY);
    spellCheckWebRequest.Method = "POST";
    spellCheckWebRequest.ContentType = "application/x-www-form-urlencoded"; // doesn't work without this

    // Create and send the request
    string body = "text=" + System.Web.HttpUtility.UrlEncode(text);
    byte[] data = Encoding.UTF8.GetBytes(body);
    spellCheckWebRequest.ContentLength = data.Length;
    using (var requestStream = spellCheckWebRequest.GetRequestStream())
        requestStream.Write(data, 0, data.Length);
    HttpWebResponse response = (HttpWebResponse)spellCheckWebRequest.GetResponse();

    // Read and parse the JSON response; get spelling corrections
    var serializer = new System.Web.Script.Serialization.JavaScriptSerializer();
    var responseStream = response.GetResponseStream();
    var jsonString = new StreamReader(responseStream, Encoding.GetEncoding("utf-8")).ReadToEnd();
    dynamic jsonResponse = serializer.DeserializeObject(jsonString);
    var flaggedTokens = jsonResponse["flaggedTokens"];

    // Construct sorted dictionary of corrections in reverse order (right to left)
    // This ensures that changes don't impact later indexes
    var corrections = new SortedDictionary<int, string[]>(Comparer<int>.Create((a, b) => b.CompareTo(a)));
    for (int i = 0; i < flaggedTokens.Length; i++)
    {
        var correction = flaggedTokens[i];
        var suggestion = correction["suggestions"][0];  // Consider only first suggestion
        if (suggestion["score"] > (decimal)0.7)         // Take it only if highly confident
            corrections[(int)correction["offset"]] = new string[]   // dict key   = offset
                { correction["token"], suggestion["suggestion"] };  // dict value = {error, correction}
    }

    // Apply spelling corrections, in order, from right to left
    foreach (int i in corrections.Keys)
    {
        var oldtext = corrections[i][0];
        var newtext = corrections[i][1];

        // Apply capitalization from original text to correction - all caps or initial caps
        if (text.Substring(i, oldtext.Length).All(char.IsUpper)) newtext = newtext.ToUpper();
        else if (char.IsUpper(text[i])) newtext = newtext[0].ToString().ToUpper() + newtext.Substring(1);

        text = text.Substring(0, i) + newtext + text.Substring(i + oldtext.Length);
    }
    return text;
}
// NOTE:
// In the following sections, we'll add code below this.

クリック時にテキストを翻訳するTranslate text on click

最後に行う必要がある作業は、ユーザー インターフェイスにある [Translate] ボタンがクリックされたときに呼び出されるメソッドの作成です。The last thing that we need to do is create a method that is invoked when the Translate button in our user interface is clicked.

  1. Visual Studio で、MainWindow.xaml.cs のタブを開きます。In Visual Studio, open the tab for MainWindow.xaml.cs.
  2. 次のコードをプロジェクト内の CorrectSpelling() メソッドの下に追加し、保存します。Add this code to your project below the CorrectSpelling() method and save:
    // ***** PERFORM TRANSLATION ON BUTTON CLICK
    private async void TranslateButton_Click(object sender, EventArgs e)
    {
        string textToTranslate = TextToTranslate.Text.Trim();
    
        string fromLanguage = FromLanguageComboBox.SelectedValue.ToString();
        string fromLanguageCode;
    
        // auto-detect source language if requested
        if (fromLanguage == "Detect")
        {
            fromLanguageCode = DetectLanguage(textToTranslate);
            if (!languageCodes.Contains(fromLanguageCode))
            {
                MessageBox.Show("The source language could not be detected automatically " +
                    "or is not supported for translation.", "Language detection failed",
                    MessageBoxButton.OK, MessageBoxImage.Error);
                return;
            }
        }
        else
            fromLanguageCode = languageCodesAndTitles[fromLanguage];
    
        string toLanguageCode = languageCodesAndTitles[ToLanguageComboBox.SelectedValue.ToString()];
    
        // spell-check the source text if the source language is English
        if (fromLanguageCode == "en")
        {
            if (textToTranslate.StartsWith("-"))    // don't spell check in this case
                textToTranslate = textToTranslate.Substring(1);
            else
            {
                textToTranslate = CorrectSpelling(textToTranslate);
                TextToTranslate.Text = textToTranslate;     // put corrected text into input field
            }
        }
        // handle null operations: no text or same source/target languages
        if (textToTranslate == "" || fromLanguageCode == toLanguageCode)
        {
            TranslatedTextLabel.Content = textToTranslate;
            return;
        }
    
        // send HTTP request to perform the translation
        string endpoint = string.Format(TEXT_TRANSLATION_API_ENDPOINT, "translate");
        string uri = string.Format(endpoint + "&from={0}&to={1}", fromLanguageCode, toLanguageCode);
    
        System.Object[] body = new System.Object[] { new { Text = textToTranslate } };
        var requestBody = JsonConvert.SerializeObject(body);
    
        using (var client = new HttpClient())
        using (var request = new HttpRequestMessage())
        {
            request.Method = HttpMethod.Post;
            request.RequestUri = new Uri(uri);
            request.Content = new StringContent(requestBody, Encoding.UTF8, "application/json");
            request.Headers.Add("Ocp-Apim-Subscription-Key", COGNITIVE_SERVICES_KEY);
            request.Headers.Add("Ocp-Apim-Subscription-Region", "westus");
            request.Headers.Add("X-ClientTraceId", Guid.NewGuid().ToString());
    
            var response = await client.SendAsync(request);
            var responseBody = await response.Content.ReadAsStringAsync();
    
            var result = JsonConvert.DeserializeObject<List<Dictionary<string, List<Dictionary<string, string>>>>>(responseBody);
            var translation = result[0]["translations"][0]["text"];
    
            // Update the translation field
            TranslatedTextLabel.Content = translation;
        }
    }
    

最初の手順では、"翻訳元" と "翻訳先" の言語およびユーザーがフォームに入力したテキストを取得します。The first step is to get the "from" and "to" languages, and the text the user entered into our form. ソース言語が [Detect] に設定されている場合、DetectLanguage() が呼び出され、ソース テキストの言語が判断されます。If the source language is set to Detect, DetectLanguage() is called to determine the language of the source text. テキストの言語が Translator でサポートされていない場合があります。The text might be in a language that the Translator doesn't support. その場合は、ユーザーに通知するメッセージが表示され、テキストを翻訳せずに戻ります。In that case, display a message to inform the user, and return without translating the text.

ソース言語が英語の場合 (指定または検出)、CorrectSpelling() でテキストのスペルを確認し、修正を適用します。If the source language is English (whether specified or detected), check the spelling of the text with CorrectSpelling() and apply any corrections. 修正されたテキストがテキスト領域に追加され、ユーザーは修正が行われたことがわかります。The corrected text is added back into the text area so that the user sees that a correction was made.

テキストを翻訳するコードには見覚えがあると思います。URI を構築し、要求を作成し、それを送信し、応答を解析します。The code to translate text should look familiar: build the URI, create a request, send it, and parse the response. JSON 配列には翻訳のオブジェクトが複数含まれている場合がありますが、このアプリで必要なのは 1 つのみです。The JSON array may contain more than one object for translation, however, our app only requires one.

要求が成功すると、TranslatedTextLabel.Contenttranslation に置き換えられ、ユーザー インターフェイスが更新されて、翻訳されたテキストが表示されます。After a successful request, TranslatedTextLabel.Content is replaced with the translation, which updates the user interface to display the translated text.

WPF アプリを実行するRun your WPF app

WPF を使用して、動作する翻訳アプリを作成しました。That's it, you have a working translation app built using WPF. このアプリを実行するには、Visual Studio の [開始] ボタンをクリックします。To run your app, click the Start button in Visual Studio.

ソース コードSource code

このプロジェクトのソース コードは、GitHub で入手できます。Source code for this project is available on GitHub.

次のステップNext steps