小戈 發表於 2025-6-21 23:29:00

WPF实现本地化多语言的几种方式

<h2 id="话不多说我们直接上源码开干">话不多说,我们直接上源码开干。</h2>
<h2 id="1第一种方式-使用字典dictionaryxaml">1.第一种方式: 使用字典Dictionary.xaml</h2>
<p><strong>搭建系统框架,使用MVVM</strong></p>
<p><strong>页面布局方式如下:</strong></p>
<pre><code>&lt;Window x:Class="WPFDemoMVVM.View.LanguageChangeView"
                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:WPFDemoMVVM.View"
                xmlns:lex="http://wpflocalizeextension.codeplex.com"
                xmlns:lang="clr-namespace:WPFDemoMVVM.Resources"
                mc:Ignorable="d"
                Title="{DynamicResource Home}" Height="300" Width="600"&gt;
        &lt;Grid&gt;
                &lt;Grid.RowDefinitions&gt;
                        &lt;RowDefinition/&gt;
                        &lt;RowDefinition/&gt;
                &lt;/Grid.RowDefinitions&gt;
                &lt;StackPanel Grid.Row="0" VerticalAlignment="Center" HorizontalAlignment="Center" &gt;
                        &lt;TextBlock Text="{DynamicResource Welcome}" FontSize="48"/&gt;

                &lt;/StackPanel&gt;
                &lt;StackPanel Grid.Row="1" Orientation="Horizontal" HorizontalAlignment="Center" VerticalAlignment="Center"&gt;
                        &lt;Button x:Name="btnEnglish" Tag="en" Content="{DynamicResource English}" Margin="10" Command="{Binding ChangeLanguageCommand}" CommandParameter="{Binding Tag, RelativeSource={RelativeSource Self}}" Width="100" Height="30"/&gt;
                        &lt;Button x:Name="btnLanguage" Tag="zh-CN" Content="{DynamicResource Chinese}" Margin="10" Command="{Binding ChangeLanguageCommand}" CommandParameter="{Binding Tag, RelativeSource={RelativeSource Self}}" Width="100" Height="30"/&gt;
                        &lt;Button Content="{DynamicResource ShowMessage}" Margin="20" Command="{Binding ShowMessageCommand}" Width="100" Height="30"&gt;&lt;/Button&gt;
                &lt;/StackPanel&gt;
        &lt;/Grid&gt;
&lt;/Window&gt;
</code></pre>
<p><strong>后端ViewModel:</strong></p>
<pre><code>using CommunityToolkit.Mvvm.ComponentModel;
using CommunityToolkit.Mvvm.Input;
using System;
using System.Collections.Generic;
using System.Globalization;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using System.Windows;
using WPFDemoMVVM.Resources;
using WPFLocalizeExtension.Engine;

namespace WPFDemoMVVM.ViewModel
{
        public partial class LanguageChangeViewModel: ObservableObject
        {

               
                private void ChangeLanguage(string languageCode)
                {
                        if (string.IsNullOrWhiteSpace(languageCode))
                                return;
                        // 切换语言资源
                        var dict = new ResourceDictionary();
                        switch (languageCode)
                        {
                                case "en":
                                        dict.Source = new Uri("Language/en_Dictionary.xaml", UriKind.Relative);
                                        break;
                                case "zh-CN":
                                        dict.Source = new Uri("Language/zh_Dictionary.xaml", UriKind.Relative);
                                        break;
                                default:
                                        return;
                        }
                        // 替换 Application 的 Resource
                        Application.Current.Resources.MergedDictionaries.Clear();
                        Application.Current.Resources.MergedDictionaries.Add(dict);
                }

               
                private void ShowMessage()
                {
                        MessageBox.Show(Application.Current.TryFindResource("Hello").ToString(), Application.Current.TryFindResource("Prompt").ToString(), MessageBoxButton.OK, MessageBoxImage.Information);
                }
        }
}
</code></pre>
<p><strong>新建两个资源文件:en_Dictionary.xaml和zh_Dictionary.xaml</strong></p>
<p>en_Dictionary.xaml如下:</p>
<pre><code>&lt;ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
                                        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"               
                                        xmlns:sys="clr-namespace:System;assembly=netstandard"&gt;
        &lt;sys:String x:Key="Home"&gt;Home&lt;/sys:String&gt;
        &lt;sys:String x:Key="MenuMsg"&gt;Menu Management&lt;/sys:String&gt;
        &lt;sys:String x:Key="Welcome"&gt;Welcome to you&lt;/sys:String&gt;
        &lt;sys:String x:Key="English"&gt;English&lt;/sys:String&gt;
        &lt;sys:String x:Key="Chinese"&gt;Chinese&lt;/sys:String&gt;
        &lt;sys:String x:Key="ShowMessage"&gt;Show Message&lt;/sys:String&gt;
        &lt;sys:String x:Key="Prompt"&gt;Prompt&lt;/sys:String&gt;
        &lt;sys:String x:Key="Hello"&gt;Hello&lt;/sys:String&gt;
&lt;/ResourceDictionary&gt;
</code></pre>
<hr>
<p>zh_Dictionary.xaml如下:</p>
<pre><code>&lt;ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
                                        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
                                        xmlns:sys="clr-namespace:System;assembly=netstandard"&gt;
        &lt;sys:String x:Key="Home"&gt;首页&lt;/sys:String&gt;
        &lt;sys:String x:Key="MenuMsg"&gt;菜单管理&lt;/sys:String&gt;
        &lt;sys:String x:Key="Welcome"&gt;欢迎你&lt;/sys:String&gt;
        &lt;sys:String x:Key="English"&gt;英文&lt;/sys:String&gt;
        &lt;sys:String x:Key="Chinese"&gt;中文&lt;/sys:String&gt;
        &lt;sys:String x:Key="ShowMessage"&gt;显示信息&lt;/sys:String&gt;
        &lt;sys:String x:Key="Prompt"&gt;提示&lt;/sys:String&gt;
        &lt;sys:String x:Key="Hello"&gt;你好&lt;/sys:String&gt;
&lt;/ResourceDictionary&gt;
</code></pre>
<p>在App.xaml中将资源合并进入项目:</p>
<pre><code>&lt;Application x:Class="WPFDemoMVVM.App"
                       xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
                       xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
                       xmlns:local="clr-namespace:WPFDemoMVVM"
                       Startup="Application_Startup"&gt;
        &lt;Application.Resources&gt;
                &lt;ResourceDictionary&gt;
                        &lt;ResourceDictionary.MergedDictionaries&gt;
                                &lt;ResourceDictionary Source="pack://application:,,,/WPFDemoMVVM;component/Language/zh_Dictionary.xaml"/&gt;
                                &lt;ResourceDictionary Source="pack://application:,,,/HandyControl;component/Themes/SkinDefault.xaml"/&gt;
                                &lt;ResourceDictionary Source="pack://application:,,,/HandyControl;component/Themes/Theme.xaml"/&gt;
                        &lt;/ResourceDictionary.MergedDictionaries&gt;
                &lt;/ResourceDictionary&gt;
        &lt;/Application.Resources&gt;
&lt;/Application&gt;
</code></pre>
<p><strong>App进程里进行初始化配置:</strong></p>
<p><img src="https://img2024.cnblogs.com/blog/2212230/202506/2212230-20250619234716937-1627097484.png"></p>
<p>效果如下图:<br>
<img src="https://img2024.cnblogs.com/blog/2212230/202506/2212230-20250619235126718-803751987.png"></p>
<p><img src="https://img2024.cnblogs.com/blog/2212230/202506/2212230-20250619235143104-205046524.png"></p>
<h2 id="2-第二种方式使用resx资源文件实现多语言本地化">2. 第二种方式,使用resx资源文件,实现多语言本地化</h2>
<p><strong>新建资源文件Lang.resx和Lang.zh-CN.resx</strong><br>
<img src="https://img2024.cnblogs.com/blog/2212230/202506/2212230-20250619235426994-898012008.png"></p>
<p><strong>新建LanguageChangeView页面布局:</strong></p>
<pre><code>&lt;Window x:Class="WPFDemoMVVM.View.LanguageChangeView"
                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:WPFDemoMVVM.View"
                xmlns:lex="http://wpflocalizeextension.codeplex.com"
                xmlns:lang="clr-namespace:WPFDemoMVVM.Resources"
                mc:Ignorable="d"
                Title="{x:Static lang:Lang.Home}" Height="300" Width="600"&gt;
        &lt;Grid&gt;
                &lt;Grid.RowDefinitions&gt;
                        &lt;RowDefinition/&gt;
                        &lt;RowDefinition/&gt;
                &lt;/Grid.RowDefinitions&gt;
                &lt;StackPanel Grid.Row="0" VerticalAlignment="Center" HorizontalAlignment="Center" &gt;
                        &lt;TextBlock Text="{x:Static lang:Lang.Welcome}" FontSize="48"/&gt;

                &lt;/StackPanel&gt;
                &lt;StackPanel Grid.Row="1" Orientation="Horizontal" HorizontalAlignment="Center" VerticalAlignment="Center"&gt;
                        &lt;Button x:Name="btnEnglish" Tag="en" Content="{x:Static lang:Lang.English}" Margin="10" Command="{Binding ChangeLanguageCommand}" CommandParameter="{Binding Tag, RelativeSource={RelativeSource Self}}" Width="100" Height="30"/&gt;
                        &lt;Button x:Name="btnLanguage" Tag="zh-CN" Content="{x:Static lang:Lang.Chinese}" Margin="10" Command="{Binding ChangeLanguageCommand}" CommandParameter="{Binding Tag, RelativeSource={RelativeSource Self}}" Width="100" Height="30"/&gt;
                        &lt;Button Content="{x:Static lang:Lang.ShowMessage}" Margin="20" Command="{Binding ShowMessageCommand}" Width="100" Height="30"&gt;&lt;/Button&gt;
                &lt;/StackPanel&gt;
        &lt;/Grid&gt;
&lt;/Window&gt;
</code></pre>
<p><strong>ViewModel页如下:</strong></p>
<pre><code>using CommunityToolkit.Mvvm.ComponentModel;
using CommunityToolkit.Mvvm.Input;
using System;
using System.Collections.Generic;
using System.Globalization;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using System.Windows;
using WPFDemoMVVM.Resources;
using WPFLocalizeExtension.Engine;

namespace WPFDemoMVVM.ViewModel
{
        public partial class LanguageChangeViewModel: ObservableObject
        {

               
                private void ChangeLanguage(string languageCode)
                {
                        //第二种方式切换语言资源
                        var culture = new CultureInfo(languageCode);
                        Thread.CurrentThread.CurrentCulture = culture;
                        Thread.CurrentThread.CurrentUICulture = culture;
                }


               
                private void ShowMessage()
                {
                        MessageBox.Show(Lang.Hello,Lang.Prompt, MessageBoxButton.OK, MessageBoxImage.Information);
                }
        }
}
</code></pre>
<h2 id="3第三种方式使用第三方库wpflocalizeextension可以实现热重载推荐使用">3.第三种方式,使用第三方库:wpflocalizeextension,可以实现热重载【推荐使用】</h2>
<p>引用三方库:wpflocalizeextension</p>
<p>视图页面LanguageChangeView 如下:<br>
导入命名空间:xmlns:lex="http://wpflocalizeextension.codeplex.com"<br>
使用绑定方式:Text="{lex:Loc WPFDemoMVVM:Lang:Welcome}"</p>
<pre><code>&lt;Window x:Class="WPFDemoMVVM.View.LanguageChangeView"
                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:WPFDemoMVVM.View"
                xmlns:lex="http://wpflocalizeextension.codeplex.com"
                xmlns:lang="clr-namespace:WPFDemoMVVM.Resources"
                mc:Ignorable="d"
                Title="{lex:Loc WPFDemoMVVM:Lang:Home}" Height="300" Width="600"&gt;
        &lt;Grid&gt;
                &lt;Grid.RowDefinitions&gt;
                        &lt;RowDefinition/&gt;
                        &lt;RowDefinition/&gt;
                &lt;/Grid.RowDefinitions&gt;
                &lt;StackPanel Grid.Row="0" VerticalAlignment="Center" HorizontalAlignment="Center" &gt;
                        &lt;TextBlock Text="{lex:Loc WPFDemoMVVM:Lang:Welcome}" FontSize="48"/&gt;
                &lt;/StackPanel&gt;
                &lt;StackPanel Grid.Row="1" Orientation="Horizontal" HorizontalAlignment="Center" VerticalAlignment="Center"&gt;
                        &lt;Button x:Name="btnEnglish" Tag="en" Content="{lex:Loc WPFDemoMVVM:Lang:English}" Margin="10" Command="{Binding ChangeLanguageCommand}" CommandParameter="{Binding Tag, RelativeSource={RelativeSource Self}}" Width="100" Height="30"/&gt;
                        &lt;Button x:Name="btnLanguage" Tag="zh-CN" Content="{lex:Loc WPFDemoMVVM:Lang:Chinese}" Margin="10" Command="{Binding ChangeLanguageCommand}" CommandParameter="{Binding Tag, RelativeSource={RelativeSource Self}}" Width="100" Height="30"/&gt;
                        &lt;Button Content="{lex:Loc WPFDemoMVVM:Lang:ShowMessage}" Margin="20" Command="{Binding ShowMessageCommand}" Width="150" Height="30"&gt;&lt;/Button&gt;
                &lt;/StackPanel&gt;
        &lt;/Grid&gt;
&lt;/Window&gt;
</code></pre>
<p>或者也可以使用如下的方式,如果整个页面都是引用同一个命名空间下的资源文件:<br>
需要设置<br>
<strong>lex:ResxLocalizationProvider.DefaultAssembly="WPFDemoMVVM";<br>
lex:ResxLocalizationProvider.DefaultDictionary="Lang";</strong></p>
<p>如果需要在设计的时候显示当前的语言的文本可以设置:<br>
<strong>lex:LocalizeDictionary.DesignCulture="zh-CN"</strong></p>
<pre><code>&lt;Window x:Class="WPFDemoMVVM.View.LanguageChangeView"
                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:WPFDemoMVVM.View"
                xmlns:lex="http://wpflocalizeextension.codeplex.com"
                xmlns:lang="clr-namespace:WPFDemoMVVM.Resources"
                lex:ResxLocalizationProvider.DefaultAssembly="WPFDemoMVVM"
                lex:ResxLocalizationProvider.DefaultDictionary="Lang"
                lex:LocalizeDictionary.DesignCulture="zh-CN"
                mc:Ignorable="d"
                Title="{lex:Loc Home}" Height="300" Width="600"&gt;
        &lt;Grid&gt;
                &lt;Grid.RowDefinitions&gt;
                        &lt;RowDefinition/&gt;
                        &lt;RowDefinition/&gt;
                &lt;/Grid.RowDefinitions&gt;
                &lt;StackPanel Grid.Row="0" VerticalAlignment="Center" HorizontalAlignment="Center" &gt;
                        &lt;TextBlock Text="{lex:Loc Welcome}" FontSize="48"/&gt;
                &lt;/StackPanel&gt;
                &lt;StackPanel Grid.Row="1" Orientation="Horizontal" HorizontalAlignment="Center" VerticalAlignment="Center"&gt;
       &lt;!--&lt;Button x:Name="btnEnglish" Tag="en" Content="{lex:Loc English}" Margin="10" Command="{Binding ChangeLanguageCommand}" CommandParameter="{Binding Tag, RelativeSource={RelativeSource Self}}" Width="100" Height="30"/&gt;
       &lt;Button x:Name="btnLanguage" Tag="zh-CN" Content="{lex:Loc Chinese}" Margin="10" Command="{Binding ChangeLanguageCommand}" CommandParameter="{Binding Tag, RelativeSource={RelativeSource Self}}" Width="100" Height="30"/&gt;--&gt;
       &lt;Button x:Name="btnEnglish" Tag="en" Content="{lex:Loc English}" Margin="10" Command="{Binding Source={x:Static lex:LocalizeDictionary.Instance},Path=SetCultureCommand}" CommandParameter="en" Width="100" Height="30"/&gt;
       &lt;Button x:Name="btnLanguage" Tag="zh-CN" Content="{lex:Loc Chinese}" Margin="10" Command="{Binding Source={x:Static lex:LocalizeDictionary.Instance},Path=SetCultureCommand}" CommandParameter="zh-CN" Width="100" Height="30"/&gt;
                        &lt;Button Content="{lex:Loc ShowMessage}" Margin="20" Command="{Binding ShowMessageCommand}" Width="150" Height="30"&gt;&lt;/Button&gt;
                &lt;/StackPanel&gt;
        &lt;/Grid&gt;
&lt;/Window&gt;
</code></pre>
<hr>
<p>viewModel实现类如下:</p>
<pre><code>using CommunityToolkit.Mvvm.ComponentModel;
using CommunityToolkit.Mvvm.Input;
using System;
using System.Collections.Generic;
using System.Globalization;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using System.Windows;
using WPFDemoMVVM.Resources;
using WPFLocalizeExtension.Engine;

namespace WPFDemoMVVM.ViewModel
{
        public partial class LanguageChangeViewModel: ObservableObject
        {
               
                private void ChangeLanguage(string languageCode)
                {
                        ////第三种方式切换语言资源
                        var culture = new CultureInfo(languageCode);
                        Thread.CurrentThread.CurrentCulture = culture;
                        Thread.CurrentThread.CurrentUICulture = culture;
                        LocalizeDictionary.Instance.Culture = culture;
                }

               
                private void ShowMessage()
                {
                        MessageBox.Show(Lang.Hello,Lang.Prompt, MessageBoxButton.OK, MessageBoxImage.Information);
                }
        }
}
</code></pre>
<p>效果如下:<br>
英文界面:<br>
<img src="https://img2024.cnblogs.com/blog/2212230/202506/2212230-20250621142058079-479559492.png"></p>
<p>中文界面:<br>
<img src="https://img2024.cnblogs.com/blog/2212230/202506/2212230-20250621142120713-1654581858.png"></p>
<h2 id="3第四种方式使用第三方库antelcati18nwpf">3.第四种方式,使用第三方库:Antelcat.I18N.WPF,</h2>
<p>引入第三方库:Antelcat.I18N.WPF,</p>
<p>然后新建LangKeys类,包装资源文件Lang:</p>
<pre><code>using Antelcat.I18N.Attributes;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace LanguageLibrary.Resources
{
       
        public partial class LangKeys
        {
        }   
}
</code></pre>
<p>视图页面如下:</p>
<pre><code>&lt;Window x:Class="WPFDemoMVVM.View.LanguageChangeView"
                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:WPFDemoMVVM.View"
                xmlns:lang="clr-namespace:WPFDemoMVVM.Resources"
                mc:Ignorable="d"
                Title="{I18N {x:Static lang:LangKeys.Home}}" Height="300" Width="600"&gt;
        &lt;Grid&gt;
                &lt;Grid.RowDefinitions&gt;
                        &lt;RowDefinition/&gt;
                        &lt;RowDefinition/&gt;
                &lt;/Grid.RowDefinitions&gt;
                &lt;StackPanel Grid.Row="0" VerticalAlignment="Center" HorizontalAlignment="Center" &gt;
                        &lt;TextBlock Text="{I18N {x:Static lang:LangKeys.Welcome}}" FontSize="48"/&gt;
                &lt;/StackPanel&gt;
                &lt;StackPanel Grid.Row="1" Orientation="Horizontal" HorizontalAlignment="Center" VerticalAlignment="Center"&gt;
                        &lt;Button x:Name="btnEnglish" Tag="en" Content="{I18N {x:Static lang:LangKeys.English}}" Margin="10" Command="{Binding ChangeLanguageCommand}" CommandParameter="{Binding Tag, RelativeSource={RelativeSource Self}}" Width="100" Height="30"/&gt;
                        &lt;Button x:Name="btnLanguage" Tag="zh-CN" Content="{I18N {x:Static lang:LangKeys.Chinese}}" Margin="10" Command="{Binding ChangeLanguageCommand}" CommandParameter="{Binding Tag, RelativeSource={RelativeSource Self}}" Width="100" Height="30"/&gt;
                        &lt;Button Content="{I18N {x:Static lang:LangKeys.ShowMessage}}" Margin="20" Command="{Binding ShowMessageCommand}" Width="150" Height="30"&gt;&lt;/Button&gt;
                &lt;/StackPanel&gt;
        &lt;/Grid&gt;
&lt;/Window&gt;
</code></pre>
<p>viewmodel类:</p>
<pre><code>using CommunityToolkit.Mvvm.ComponentModel;
using CommunityToolkit.Mvvm.Input;
using System;
using System.Collections.Generic;
using System.Globalization;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using System.Windows;
using WPFDemoMVVM.Resources;
using WPFLocalizeExtension.Engine;

namespace WPFDemoMVVM.ViewModel
{
        public partial class LanguageChangeViewModel: ObservableObject
        {
               
                private void ChangeLanguage(string languageCode)
                {
                        ////第四种方式换语言资源
                        var culture = new CultureInfo(languageCode);
                        Thread.CurrentThread.CurrentCulture = culture;
                        Thread.CurrentThread.CurrentUICulture = culture;
                        I18NExtension.Culture = culture;
                }

               
                private void ShowMessage()
                {
                        MessageBox.Show(Lang.Hello,Lang.Prompt, MessageBoxButton.OK, MessageBoxImage.Information);
                }
        }
}
</code></pre>
<p>效果如下:<br>
英文界面:<br>
<img src="https://img2024.cnblogs.com/blog/2212230/202506/2212230-20250621142058079-479559492.png"></p>
<p>中文界面:<br>
<img src="https://img2024.cnblogs.com/blog/2212230/202506/2212230-20250621142120713-1654581858.png"></p>
<p>源码地址:https://gitee.com/chenshibao/wpfdemo.git</p>
<p>可参考学习开源项目:<br>
WPFLocalizeExtension:https://github.com/XAMLMarkupExtensions/WPFLocalizeExtension<br>
Antelcat.I18N:https://github.com/Antelcat/I18N</p>
<p><strong>如果本文介绍对你有帮助,可以一键四连:点赞+评论+收藏+推荐,谢谢!</strong></p><br><br>
来源:https://www.cnblogs.com/chenshibao/p/18937359
頁: [1]
查看完整版本: WPF实现本地化多语言的几种方式