除了前面介紹的三種方式之外,這篇是這一系列文的最後一種方式了。只要簡單的透過XmlDataProvider和強大的DataBinding的功能,就一樣可以做出有多語系功能的WPF應用程式。另外,這個方式也一樣能達到執行時期動態的語系切換功能喔!!
廢話不多說,直接開始吧!!
除了前面介紹的三種方式之外,這篇是這一系列文的最後一種方式了。只要簡單的透過XmlDataProvider和強大的DataBinding的功能,就一樣可以做出有多語系功能的WPF應用程式。另外,這個方式也一樣能達到執行時期動態的語系切換功能喔!!
廢話不多說,直接開始吧!!
Step 1:建立WPF應用程式
首先,跟前面幾篇一樣,請自行建立一個WPF專案,有看前三篇的朋友們應該就對下面的使用者介面熟悉到不行了~
而該介面原始Xaml如下:
基本上到這邊應該都不會有什麼問題,大家可以執行看看自己寫的小範例,看看是不是能正常的運作,正常的話就可以繼續下一個步驟囉!!
Step 2:建立存放語系Xml檔的資料夾
即然要使用XmlDataProvider,顧名思義,我們要使用Xml檔來定義每個語系的文字內容,所以透過VisualStudio的SolutionExplorer在專案中建立一個用來存放語系Xml檔的資料夾吧!!這邊我將存放語系Xml檔的資料夾取名為Cultures。
Step 3:在建立好的資料夾中新增預設語系的Xml檔
在剛剛建立好的資料夾裡建立一個用來當預設語系的Xml檔,我將它取名為Language.xml,內容如下:
Step 4:複製並修改預設語系的Xml檔,以建立其他語系資料
這邊我將Language.xml複製了兩份,並分別更名為Language.en-US.xml與Language.zh-TW.xml,以下是它們的內容:
接著在請選取非預設語系的xml檔,並在Properties視窗中將它們的BuildAction的值改為Content、Copy to Output Dictionary的值改為Copy always。
Step 5:加入System.Windows.Form參考
會要做這一步,是為了我們要在執行期的時候動態的透過程式去取得可用的語系Xml檔。
Step 6:在Settings.settings檔中加入預設語系的設定值
透過Solution Explorer,開啟位於專案中Properties資料夾裡面的Settings.settings檔。
接著在裡面加入一組名稱為DefaultCulture,型別為CultureInfo,值為en-US的設定,方法如下:
在第一個空白列的Name欄位中輸入DefaultCulture,然後在Type下拉選單中點選最下方的Browse...,並在跳出來的Select a Type視窗中如下圖點選到System.Globalization.CultureInfo。
最後在Value欄位中輸入en-US,完成後請記得存檔喔!!
Step 7:在專案中加入多語系小幫手Class檔
接下來的動作要寫一大堆的程式,不過我已經幫大家寫好了~當作是我送給大家的禮物,還請大家笑納(不過這篇的CulturesHelper和其他方式所要使用的CulturesHelper內容不一樣喔,千萬別搞混了!!)~
加入之後,也請記得依照自己的需求在該Class中加入NameSpace喔!!還有,也請依照自己的Xml檔的檔名和存放的資料夾名稱,自行修改_resourcePrefix和_culturesFolder的值。
Step 8:修改App.xaml檔
接著我們要在App.xaml中加入一個XmlDataProvider以便用來存取Xml內的資源,並且讓控制項進行DataBinding,這邊請跟我一樣使用xmlLanguageProvider做為x:Key的值(如果值不一樣的話,CulturesHelper得跟著配合修改喔!!)如果要修改設計階段使用的語系,也是直接在這邊修改預設使用的Xml檔就可以囉!
Step 9:透過DataBinding將相對應的資源繫結到控制項
接著我們只需要透過簡單的DataBinding,把Source為StaticResource xmlLanguageProvider,並且把Path設定為Xml中要繫結項目的XPath即可~
當然~這個步驟也可以透過Expression Blend來進行喔!!
例如我想針對Languages:這個TextBlock的Text屬性設定DataBinding,我只需要從Blend中點選Text右邊的Advanced options小白點,並且在跳出來的選單中點選DataBinding,就會跳出Create Data Binding視窗,我們只要將Data source設為xmlLanguageProvider,接著在右邊的Fields欄位中選取我們要繫結到的XPath就行啦!!
來看看繫結完的MainWindow.xaml會變怎樣吧~
<Window xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:local="clr-namespace:Wpf_XmlDataProvider"
x:Class="Wpf_XmlDataProvider.MainWindow" mc:Ignorable="d" d:DesignWidth="800" d:DesignHeight="600"
Title="MainWindow" Height="Auto" Width="Auto">
<Window.Resources>
<local:CulturesHelper x:Key="CulturesHelperDataSource" d:IsDataSource="True" />
</Window.Resources>
<Grid DataContext="{Binding Source={StaticResource xmlLanguageProvider}}">
<Border BorderBrush="#FF646464" BorderThickness="2" HorizontalAlignment="Center" Height="300"
VerticalAlignment="Center" Width="400" CornerRadius="10" Background="White">
<Border.Effect>
<DropShadowEffect Opacity="0.5" />
</Border.Effect>
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="125" />
<ColumnDefinition Width="0.646*" />
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="0.2*" />
<RowDefinition Height="0.2*" />
<RowDefinition Height="0.2*" />
<RowDefinition Height="0.2*" />
<RowDefinition Height="0.2*" />
</Grid.RowDefinitions>
<TextBlock x:Name="textBlock" HorizontalAlignment="Center" TextWrapping="Wrap"
VerticalAlignment="Center" Grid.ColumnSpan="2" Text="WPF Multilingual Sample" FontSize="24"
Foreground="#FF323232" />
<TextBlock x:Name="textBlock3" TextWrapping="Wrap" Text="{Binding XPath=/LangSettings/UserAccount}"
HorizontalAlignment="Left" VerticalAlignment="Center" Grid.Row="1" Margin="20,0,0,0"
FontSize="16" />
<ComboBox x:Name="comboBox" d:LayoutOverrides="Height" Grid.Row="1" Grid.Column="1"
VerticalAlignment="Center" Margin="10" FontSize="16" DisplayMemberPath="DisplayName"
DataContext="{Binding Source={StaticResource CulturesHelperDataSource}}"
ItemsSource="{Binding SupportedCultures}" />
<TextBlock x:Name="textBlock2" TextWrapping="Wrap" HorizontalAlignment="Left" VerticalAlignment="Center"
Grid.Row="2" Margin="20,0,0,0" FontSize="16" Text="{Binding XPath=UserAccount}" />
<TextBox x:Name="textBox" TextWrapping="Wrap" Grid.Column="1" Grid.Row="2" Margin="10" FontSize="16"
VerticalAlignment="Center" />
<TextBlock x:Name="textBlock1" TextWrapping="Wrap" HorizontalAlignment="Left" VerticalAlignment="Center"
Grid.Row="3" Margin="20,0,0,0" FontSize="16" Text="{Binding XPath=Password}" />
<TextBox x:Name="textBox1" TextWrapping="Wrap" Grid.Row="3" Grid.Column="1" Margin="10" FontSize="16"
VerticalAlignment="Center" />
<StackPanel Grid.Row="4" Grid.ColumnSpan="2" VerticalAlignment="Center" HorizontalAlignment="Center"
Orientation="Horizontal">
<Button x:Name="button" Content="{Binding XPath=Ok}" Width="75" Margin="10" FontSize="16" />
<Button x:Name="button1" Content="{Binding XPath=Cancel}" Width="75" Margin="10" FontSize="16" />
</StackPanel>
</Grid>
</Border>
</Grid>
</Window>
要取得有哪些語系可用的話,只需要像上面的例子一樣,將CulturesHelper設為DataSource,再透過它的SupportedCultures屬性,就可以取出偵測到可用的語系有哪些。
Step 10:加入動態切換語系的部份
最後,說好的執行時期動態切換呢!?跟這系列文章前幾篇的方式一樣,只需要在語言下拉選單的選項被改變了之後,呼叫CulturesHelper中的ChangeCulture方法就行啦!!
來看看執行的畫面~
切換!!~~
大功告成~~
最後的最後,一樣奉上成品的原始碼,請自行服用: