Skip to main content

WPF C#/VB
Make Your Own Translator App

C#

// AZUL CODING ---------------------------------------
// WPF C#/VB - Make Your Own Translator App
// https://youtu.be/6Zeinp1kvCg


using System.Windows;
using System.Windows.Controls;
using System.IO;
using Microsoft.Win32;
using DeepL;

namespace AzulTranslator
{
    /// <summary>
    /// Interaction logic for MainWindow.xaml
    /// </summary>
    public partial class MainWindow : Window
    {
        // Replace <YOUR API KEY> with your DeepL API key which you can get from:
        // https://www.deepl.com/pro

        private readonly string APIKey = "<YOUR API KEY>";
        private readonly Translator DeepLTranslator;

        private string? GlossaryID;
        private readonly OpenFileDialog CSVOpenDialog = new()
        {
            Title = "Open a CSV file",
            Filter = "CSV Files (*.csv)|*.csv"
        };
        private readonly OpenFileDialog DocumentOpenDialog = new()
        {
            Title = "Open a document to translate",
            Filter = "Supported Files (*.docx,*.pdf)|*.docx;*.pdf"

            // Other formats are supported, see:
            // https://developers.deepl.com/docs/api-reference/document
        };

        public MainWindow()
        {
            InitializeComponent();
            DeepLTranslator = new(APIKey);

            DeepLTranslator.GetSourceLanguagesAsync().ContinueWith(task =>
            {
                foreach (var language in task.Result)
                {
                    Dispatcher.Invoke(() =>
                    {
                        SourceLanguage.Items.Add(new ComboBoxItem()
                        {
                            Content = language.Name,
                            Tag = language.Code
                        });
                    });
                }
            });

            DeepLTranslator.GetTargetLanguagesAsync().ContinueWith(task =>
            {
                foreach (var language in task.Result)
                {
                    Dispatcher.Invoke(() =>
                    {
                        TargetLanguage.Items.Add(new ComboBoxItem()
                        {
                            Content = language.Name,
                            Tag = language.Code
                        });
                    });
                }

                Dispatcher.Invoke(() => TargetLanguage.SelectedIndex = 0);
            });
        }

        private (string?, string) GetSourceAndTargetLanguages()
        {
            var source = (string?)((ComboBoxItem)SourceLanguage.SelectedItem).Tag;
            var target = (string)((ComboBoxItem)TargetLanguage.SelectedItem).Tag;

            return (source, target);
        }

        private async void TranslateBtn_Click(object sender, RoutedEventArgs e)
        {
            try
            {
                (string? source, string target) = GetSourceAndTargetLanguages();
                TranslateBtn.IsEnabled = false;

                TargetTxt.Text = (await DeepLTranslator.TranslateTextAsync(
                    SourceTxt.Text, source, target, new TextTranslateOptions()
                    {
                        Formality = Formality.Default,
                        PreserveFormatting = false,
                        TagHandling = null,
                        GlossaryId = GlossaryID
                    })).Text;
            }
            catch
            {
                MessageBox.Show("An error occurred while translating the text.");
            }
            finally
            {
                TranslateBtn.IsEnabled = true;
            }
        }

        private async void GlossaryBtn_Click(object sender, RoutedEventArgs e)
        {
            if (GlossaryTxt.Text == "Remove glossary")
            {
                GlossaryID = null;
                GlossaryTxt.Text = "Upload glossary";
                SourceLanguage.IsEnabled = true;
                TargetLanguage.IsEnabled = true;
            }
            else if (CSVOpenDialog.ShowDialog() == true)
            {
                try
                {
                    var csvStream = File.OpenRead(CSVOpenDialog.FileName);
                    string id = Guid.NewGuid().ToString();
                    (string? source, string target) = GetSourceAndTargetLanguages();

                    // Note that some languages might not be supported for glossaries, see:
                    // https://developers.deepl.com/docs/api-reference/glossaries

                    var glossary = await DeepLTranslator.CreateGlossaryFromCsvAsync(
                        id, source ?? LanguageCode.English, target, csvStream);

                    GlossaryID = glossary.GlossaryId;
                    GlossaryTxt.Text = "Remove glossary";
                    SourceLanguage.IsEnabled = false;
                    TargetLanguage.IsEnabled = false;

                    MessageBox.Show("Glossary applied successfully.");
                }
                catch
                {
                    MessageBox.Show("An error occurred while creating the glossary.");
                }
            }
        }

        private async void DocumentBtn_Click(object sender, RoutedEventArgs e)
        {
            if (DocumentOpenDialog.ShowDialog() == true)
            {
                try
                {
                    (string? source, string target) = GetSourceAndTargetLanguages();

                    string translatedFileName = Path.GetDirectoryName(DocumentOpenDialog.FileName) + "\\" +
                        Path.GetFileNameWithoutExtension(DocumentOpenDialog.FileName) + "_translated" +
                        Path.GetExtension(DocumentOpenDialog.FileName);

                    IsEnabled = false;

                    await DeepLTranslator.TranslateDocumentAsync(
                        new FileInfo(DocumentOpenDialog.FileName), new FileInfo(translatedFileName),
                        source ?? LanguageCode.English, target, new DocumentTranslateOptions()
                        {
                            Formality = Formality.Default,
                            GlossaryId = GlossaryID
                        });

                    MessageBox.Show("Document translated successfully.");
                }
                catch
                {
                    MessageBox.Show("An error occurred while translating the document.");
                }
                finally
                {
                    IsEnabled = true;
                }
            }
        }
    }
}

Enjoying this tutorial?


VB.NET

' AZUL CODING ---------------------------------------
' WPF C#/VB - Make Your Own Translator App
' https://youtu.be/6Zeinp1kvCg


Imports System.IO
Imports Microsoft.Win32
Imports DeepL

Class MainWindow

    ' Replace <YOUR API KEY> with your DeepL API key which you can get from:
    ' https://www.deepl.com/pro

    Private ReadOnly APIKey As String = "<YOUR API KEY>"
    Private ReadOnly DeepLTranslator As Translator

    Private GlossaryID As String
    Private ReadOnly CSVOpenDialog As New OpenFileDialog With {
        .Title = "Open a CSV file",
        .Filter = "CSV Files (*.csv)|*.csv"
    }
    Private ReadOnly DocumentOpenDialog As New OpenFileDialog With {
        .Title = "Open a document to translate",
        .Filter = "Supported Files (*.docx,*.pdf)|*.docx;*.pdf"
    }
    ' Other formats are supported, see:
    ' https://developers.deepl.com/docs/api-reference/document

    Public Sub New()
        InitializeComponent()
        DeepLTranslator = New Translator(APIKey)

        DeepLTranslator.GetSourceLanguagesAsync().ContinueWith(
            Sub(task)
                For Each lang In task.Result
                    Dispatcher.Invoke(
                        Sub()
                            SourceLanguage.Items.Add(New ComboBoxItem With {
                                .Content = lang.Name,
                                .Tag = lang.Code
                            })
                        End Sub)
                Next
            End Sub)

        DeepLTranslator.GetTargetLanguagesAsync().ContinueWith(
            Sub(task)
                For Each lang In task.Result
                    Dispatcher.Invoke(
                        Sub()
                            TargetLanguage.Items.Add(New ComboBoxItem With {
                                .Content = lang.Name,
                                .Tag = lang.Code
                            })
                        End Sub)
                Next

                Dispatcher.Invoke(Sub() TargetLanguage.SelectedIndex = 0)
            End Sub)
    End Sub

    Private Function GetSourceAndTargetLanguages() As (source As String, target As String)
        Dim source As String = SourceLanguage.SelectedItem.Tag
        Dim target As String = TargetLanguage.SelectedItem.Tag

        Return (source, target)
    End Function

    Private Async Sub TranslateBtn_Click(sender As Object, e As RoutedEventArgs)
        Try
            Dim langs = GetSourceAndTargetLanguages()
            TranslateBtn.IsEnabled = False

            TargetTxt.Text = (Await DeepLTranslator.TranslateTextAsync(
                SourceTxt.Text, langs.source, langs.target,
                New TextTranslateOptions With {
                    .Formality = Formality.Default,
                    .PreserveFormatting = False,
                    .TagHandling = Nothing,
                    .GlossaryId = GlossaryID
                })).Text

        Catch
            MessageBox.Show("An error occurred while translating the text.")
        Finally
            TranslateBtn.IsEnabled = True
        End Try
    End Sub

    Private Async Sub GlossaryBtn_Click(sender As Object, e As RoutedEventArgs)
        If GlossaryTxt.Text = "Remove glossary" Then
            GlossaryID = Nothing
            GlossaryTxt.Text = "Upload glossary"
            SourceLanguage.IsEnabled = True
            TargetLanguage.IsEnabled = True

        ElseIf CSVOpenDialog.ShowDialog() = True Then
            Try
                Dim csvStream = File.OpenRead(CSVOpenDialog.FileName)
                Dim id As String = Guid.NewGuid().ToString()
                Dim langs = GetSourceAndTargetLanguages()

                ' Note that some languages might not be supported for glossaries, see:
                ' https://developers.deepl.com/docs/api-reference/glossaries

                Dim glossary = Await DeepLTranslator.CreateGlossaryFromCsvAsync(
                    id, If(langs.source, LanguageCode.English), langs.target, csvStream)

                GlossaryID = glossary.GlossaryId
                GlossaryTxt.Text = "Remove glossary"
                SourceLanguage.IsEnabled = False
                TargetLanguage.IsEnabled = False

                MessageBox.Show("Glossary applied successfully.")
            Catch
                MessageBox.Show("An error occurred while creating the glossary.")
            End Try
        End If
    End Sub

    Private Async Sub DocumentBtn_Click(sender As Object, e As RoutedEventArgs)
        If DocumentOpenDialog.ShowDialog() = True Then
            Try
                Dim langs = GetSourceAndTargetLanguages()

                Dim translatedFileName As String = Path.GetDirectoryName(DocumentOpenDialog.FileName) & "\" &
                    Path.GetFileNameWithoutExtension(DocumentOpenDialog.FileName) & "_translated" &
                    Path.GetExtension(DocumentOpenDialog.FileName)

                IsEnabled = False

                Await DeepLTranslator.TranslateDocumentAsync(
                    New FileInfo(DocumentOpenDialog.FileName), New FileInfo(translatedFileName),
                    If(langs.source, LanguageCode.English), langs.target,
                    New DocumentTranslateOptions With {
                        .Formality = Formality.Default,
                        .GlossaryId = GlossaryID
                    })

                MessageBox.Show("Document translated successfully.")
            Catch
                MessageBox.Show("An error occurred while translating the document.")
            Finally
                IsEnabled = True
            End Try
        End If
    End Sub
End Class

XAML

<!-- AZUL CODING --------------------------------------- -->
<!-- WPF C#/VB - Make Your Own Translator App -->
<!-- https://youtu.be/6Zeinp1kvCg -->


<Window x:Class="AzulTranslator.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"
        mc:Ignorable="d"
        Title="Azul Coding - Translator" Height="350" Width="600" MinWidth="450" MinHeight="300">
    <Grid Margin="15">
        <Grid.ColumnDefinitions>
            <ColumnDefinition Width="*"/>
            <ColumnDefinition Width="*"/>
        </Grid.ColumnDefinitions>
        <Grid.RowDefinitions>
            <RowDefinition Height="Auto"/>
            <RowDefinition Height="Auto"/>
            <RowDefinition Height="*"/>
            <RowDefinition Height="Auto"/>
        </Grid.RowDefinitions>
        <Label x:Name="TitleLbl" Grid.ColumnSpan="2" Content="Translator" Padding="5,0,5,5" Margin="0,0,0,15" FontWeight="SemiBold" FontSize="16" BorderBrush="DodgerBlue" BorderThickness="0,0,0,2"/>

        <ComboBox x:Name="SourceLanguage" Grid.Column="0" Grid.Row="1" Width="150" HorizontalAlignment="Left" Padding="8,4" Margin="5,0,0,10" FontSize="14" SelectedIndex="0">
            <ComboBoxItem Content="Detect language"/>
        </ComboBox>
        <ComboBox x:Name="TargetLanguage" Grid.Column="1" Grid.Row="1" Width="150" HorizontalAlignment="Left" Padding="8,4" Margin="5,0,0,10" FontSize="14"/>

        <TextBox x:Name="SourceTxt" Grid.Column="0" Grid.Row="2" TextWrapping="Wrap" AcceptsReturn="True" Padding="5" Margin="0,0,5,0" FontSize="18"/>
        <TextBox x:Name="TargetTxt" Grid.Column="1" Grid.Row="2" IsReadOnly="True" TextWrapping="Wrap" Padding="5" Margin="5,0,0,0" FontSize="18"/>

        <StackPanel Grid.Column="0" Grid.Row="3" Grid.ColumnSpan="2" HorizontalAlignment="Left" Orientation="Horizontal" Margin="0,10,0,0">
            <Button Name="TranslateBtn" Click="TranslateBtn_Click" Padding="10,5" Background="#f0f0f0">
                <StackPanel Orientation="Horizontal" VerticalAlignment="Center">
                    <Image Height="24" Width="24" Source="https://img.icons8.com/fluency/48/language.png"/>
                    <TextBlock Text="Translate" VerticalAlignment="Center" FontSize="14" Margin="10,0,5,2" FontWeight="SemiBold"/>
                </StackPanel>
            </Button>
            <Button Name="GlossaryBtn" Click="GlossaryBtn_Click" Padding="10,5" Background="#f0f0f0" Margin="10,0,0,0">
                <StackPanel Orientation="Horizontal" VerticalAlignment="Center">
                    <Image Height="24" Width="24" Source="https://img.icons8.com/fluency/48/books.png"/>
                    <TextBlock x:Name="GlossaryTxt" Text="Upload glossary" VerticalAlignment="Center" FontSize="14" Margin="10,0,5,2"/>
                </StackPanel>
            </Button>
            <Button Name="DocumentBtn" Click="DocumentBtn_Click" Padding="10,5" Background="#f0f0f0" Margin="10,0,0,0">
                <StackPanel Orientation="Horizontal" VerticalAlignment="Center">
                    <Image Height="24" Width="24" Source="https://img.icons8.com/fluency/48/upload-2.png"/>
                    <TextBlock Text="Upload document" VerticalAlignment="Center" FontSize="14" Margin="10,0,5,2"/>
                </StackPanel>
            </Button>
        </StackPanel>
    </Grid>
</Window>