[Universal Apps] 多國語系開發 -- 讓使用者選擇語系(2)

簡單的入門基礎有了, 這一篇來做個比較有趣的課題, 一般的多國語系做法會讓UI 語系跟隨著使用者在設定中的預設語系改變, 但有些時候還是要考慮使用者可以在程式中使用手動的方式修改語系. 作法上並不困難, 讓我們繼續看下去.



        簡單的入門基礎有了, 這一篇來做個比較有趣的課題, 一般的多國語系做法會讓UI 語系跟隨著使用者在設定中的預設語系改變, 但有些時候還是要考慮使用者可以在程式中使用手動的方式修改語系. 作法上並不困難, 讓我們繼續看下去.

 

 

       首先我們開啟一個新的 Universal Apps 的專案, 利用基本頁面設計兩個簡單的畫面 MainPage 與 SubPage

 

 

       MainPage

   1: <Page
   2:     x:Class="ManualLanguageChangeApp00.MainPage"
   3:     xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
   4:     xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
   5:     xmlns:local="using:ManualLanguageChangeApp00"
   6:     xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
   7:     xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
   8:     mc:Ignorable="d"
   9:     Background="{ThemeResource ApplicationPageBackgroundThemeBrush}">
  10:  
  11:     <Grid x:Name="LayoutRoot">
  12:  
  13:         <Grid.ChildrenTransitions>
  14:             <TransitionCollection>
  15:                 <EntranceThemeTransition/>
  16:             </TransitionCollection>
  17:         </Grid.ChildrenTransitions>
  18:  
  19:         <Grid.RowDefinitions>
  20:             <RowDefinition Height="Auto"/>
  21:             <RowDefinition Height="*"/>
  22:         </Grid.RowDefinitions>
  23:  
  24:         <!-- 標題面板 -->
  25:         <StackPanel Grid.Row="0" Margin="19,0,0,0">
  26:             <TextBlock x:Uid="AppTitle" Style="{ThemeResource TitleTextBlockStyle}" Margin="0,12,0,0"/>           
  27:         </StackPanel>
  28:  
  29:         <!--TODO: 內容應該放在下列格線內-->
  30:         <Grid Grid.Row="1" x:Name="ContentRoot" Margin="19,9.5,19,0">
  31:             <Button x:Uid="SettingButton" Click="SettingButton_Click"/>
  32:         </Grid>
  33:     </Grid>
  34: </Page>
 

        SubPage

   1: <Page
   2:     x:Class="ManualLanguageChangeApp00.SubPage"
   3:     xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
   4:     xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
   5:     xmlns:local="using:ManualLanguageChangeApp00"
   6:     xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
   7:     xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
   8:     mc:Ignorable="d"
   9:     Background="{ThemeResource ApplicationPageBackgroundThemeBrush}">
  10:  
  11:     <Grid x:Name="LayoutRoot">
  12:  
  13:         <Grid.ChildrenTransitions>
  14:             <TransitionCollection>
  15:                 <EntranceThemeTransition/>
  16:             </TransitionCollection>
  17:         </Grid.ChildrenTransitions>
  18:  
  19:         <Grid.RowDefinitions>
  20:             <RowDefinition Height="Auto"/>
  21:             <RowDefinition Height="*"/>
  22:         </Grid.RowDefinitions>
  23:  
  24:         <!-- 標題面板 -->
  25:         <StackPanel Grid.Row="0" Margin="19,0,0,0">
  26:             <TextBlock x:Uid="AppTitle" Style="{ThemeResource TitleTextBlockStyle}" Margin="0,12,0,0"/>          
  27:         </StackPanel>
  28:  
  29:         <!--TODO: 內容應該放在下列格線內-->
  30:         <Grid Grid.Row="1" x:Name="ContentRoot" Margin="19,9.5,19,0">
  31:             <StackPanel >
  32:                 <Button x:Uid="ByPhoneSettingButton" Click="ByPhoneSettingButton_Click"/>
  33:                 <Button x:Uid="EnglishButton" Click="EnglishButton_Click"/>
  34:                 <Button x:Uid="ZhTwButton" Click="ZhTwButton_Click"/>
  35:             </StackPanel>
  36:         </Grid>
  37:     </Grid>
  38: </Page>

 

 

 

        為畫面上的元素建立兩個資源檔分別是 en 和 zh-tw

resw_en

resw_tw

 

 

 

        在 MainPage 中加入瀏覽到 SubPage 的程式碼

   1: private void SettingButton_Click(object sender, RoutedEventArgs e)
   2: {
   3:     Frame.Navigate(typeof(SubPage)); 
   4: }

 

 

        重頭戲來了, 在 Universal Apps 中可以利用改變現有的 ResoureContext 來指定要用哪一個資源的,  ResourceContext.GetForCurrentView() 這個靜態方法提供了我們取得目前所使用的 ResourceContext,只要改變 ResourceContext 的限定詞對應, 就可以變更它的來源.

 

 

        所以我們在 SubPage 中加入以下的程式碼

   1: private void ByPhoneSettingButton_Click(object sender, RoutedEventArgs e)
   2: {
   3:     ResourceContext.GetForCurrentView().Reset();
   4:     Frame.GoBack();
   5: }
   6:  
   7: private void EnglishButton_Click(object sender, RoutedEventArgs e)
   8: {
   9:     ResourceContext.GetForCurrentView().QualifierValues["language"] = "en";
  10:     Frame.GoBack();
  11: }
  12:        
  13:  
  14: private void ZhTwButton_Click(object sender, RoutedEventArgs e)
  15: {
  16:     ResourceContext.GetForCurrentView().QualifierValues["language"] = "zh-tw";
  17:     Frame.GoBack();
  18: }

 

 

        ResourceContext.GetForCurrentView().QualifierValues["language"]  會取得語言限定詞的對應,只要將這個值改為 en , 他就會取用在 Strings\en 目錄下的字串資源,另外 Reset 方法會回復資源成原來的預設值. 很簡單的對不對, 這樣就可以做出既可以對應手機語系設定, 又可以讓使用者在程式內手動更改語系的功能了.