您的位置:澳门新葡萄京最大平台 > www.4996.com > 本地化入门

本地化入门

发布时间:2019-12-10 18:45编辑:www.4996.com浏览(143)

    1. 前言

    上风流倜傥篇小说介绍了各样WPF本地化的入门知识,那篇小说介绍UWP本地化的入门知识。

    2. 行使resw财富文件贯彻本地化

    在那前的XAML平台,resx资源文件是大器晚成种很实惠的本地化方案,但在UWP中微软又重新推荐x:Uid方案,暗中认可的能源文件也成为resw能源文件。即使后缀名只差了几个假名,但利用办法完全不一样。最关键的分别是resw财富文件不会创立对应的Designer.cs类,这就引致本地化的完成方案完全分歧。

    图片 1

    2.1 在XAML中贯彻当地化

    在XAML中落实本地化的长河很简短。首先在品种中新建"strings"文件夹,在"strings"文夹下开创"en-US"和"zh-CN"文件夹,并在三个文本夹中分别拉长"Resources.resw"资源文件。最后目录构造如下:
    图片 2

    在zh-CNResources.resw和en-USResources.resw增添两个新能源,分别是UsernameTextBox.Width和UsernameTextBox.Header:
    图片 3

    在XAML中加多叁个TextBox,设置x:Uid为UsernameTextBox,x:Uid将XAML成分和财富文件中的财富进行关联:

    <TextBox x:Uid="UsernameTextBox"/>
    

    运维后就可以以看见到UsernameTextBox的Header设置为"顾客名",Width为100。

    在“设置区域和言语”上校"English"设置为私下认可语言,再一次运转应用可以预知到运转在乌克兰(УКРАЇНА卡塔尔语境遇下的效用。
    图片 4

    诸如此比大旨的本地化功效就兑现了。这种本地化方式有如下优点:

    • 轻松急迅,轻易上手
    • 语法轻松,不须要Binding等文化
    • 能够钦赐率性属性进行本地化
    • 支持CLR属性

    除去,上黄金时代篇小说提到的ResXManager也支持Resw财富文件,还足以选择多语言应用工具包对能源文件进行保管,乐乎的那篇文章页对那一个工具举办了详尽介绍:
    Win10 UWP 开荒体系:使用多语言工具包让应用支撑多语言

    抑或参谋那一个录像:
    Windows 10 Apps Designing for Global Customers

    2.2 关联到任何财富文件

    UI元素暗中同意与Resources.resw实行关联,如果须要和其它国资本源文件涉及,能够加上财富文件的路径。如必要与/OtherResources.resw中的能源事关,x:Uid的语法如下:

    x:Uid="/OtherResources/AddressTextBox"
    

    2.3 附加属性的本地化

    对系统提供的增大属性,财富的称号语法如下:

    UsernameTextBox.Grid.Row
    

    对自定义附加属性,语法稍稍复杂一些:

    ShowMessageButton.[using:LocalizationDemoUwp]ButtonEx.Content
    

    古怪的是,就这么一贯运维应用会报错。唯有采用这几个能源的UI成分已经有这些附加属性的值才具健康运维,一言以蔽之正是急需随意为那么些附加属性设置四个值:

    <Button Margin="5" x:Uid="ShowMessageButton"  local:ButtonEx.Content="ssssss"/>
    

    2.4 其余财富的本地化

    而外字符串能源,其余能源的本地化格局无需设置x:Uid,只须求树立对应语言的目录构造及命名就足以在XAML中一贯援引。如项目中好似下两张图片:
    图片 5

    在XAML中能够直接通过Images/Flag.png援用。路径中的"zh-CN"、"en-US"称为财富节制符,用于协助三种呈现比例、UI 语言、高比较度设置等,具体可参照Load images and assets tailored for scale, theme, high contrast, and others 。

    2.5 在代码里拜会财富

    在代码中访谈财富的代码如下:

    var resourceLoader = ResourceLoader.GetForCurrentView();
    var currentLanguage = resourceLoader.GetString("CurrentLanguage");
    resourceLoader = ResourceLoader.GetForCurrentView("OtherResources");
    var message = resourceLoader.GetString("Message");
    

    上边的代码中,currentLanguage从暗中同意的能源文件Resources.resw中赢得,resourceLoader 没有须要钦点资源文件的名称;而message 则从OtherResources.resw获取,resourceLoader 要求内定能源文件的名号。

    如供给选拔任何类库中的财富,代码如下:

    resourceLoader = ResourceLoader.GetForCurrentView("LocalizationDemoUwp.ResourceLibrary/Resources");
    currentLanguage = resourceLoader.GetString("CurrentLanguage");
    

    固然如此语法简单,但足以见见最大的标题是财富的称呼未有智能感知和谬误提醒,那样使用财富超轻巧失误。

    图片 6

    如上海教室所示,对不当的能源名称,ReSharper会有错误提醒,然而这种协会ResourceLoader的措施已经被标志为Deprecated并提示使用GetForCurrentView获取ResourceLoader,而选取GetForCurrentView的气象下ReSharper又从未不当提醒。不精通ReSharper何时技巧支撑在GetForCurrentView的方法下显得错误提醒(笔者设置的ReSharper已然是最新的2017.2)。

    2.6 存在的主题素材

    以此本地化方案固然简易,但本人觉着很难使用,因为那么些方案存在重重标题。

    先是是安顿性时扶助,对本地化来讲,设计时支持至关心注重要包涵3有个别:

    • 在编写XAML时能够赢得能源的智能感知
    • 有完全的布置视图
    • 在不一致语言之间切换

    首先点,未有,並且写错属性名称还不会在编写翻译时报错,而是用最严寒的措施表现:运维时崩溃。

    其次点,在Fall Creators Update (16299卡塔尔从前,未有,设计视图一片空白。也能够不管写一些内容(如TextBox x:Uid="UsernameTextBox" Header="(here is header)")以援助设计。但在XAML中写的其它内容都也许被能源文件覆盖,无论是公事依然大小、对齐格局或别的具备属性对XAML的编者来讲都是不可控的,不到骨子里运转时平昔不清楚UI的末段效果,那就很核实本地化职员和测量试验人士。在Fall Creators Update未来终于得以在兼备视图看到本地化的功能,那只好说是庞大的开荒进取。

    其三点,如今来看做不到。

    其他,能源处理也是个很麻烦的标题。同多个字符串,即便要对应TextBlock.Text、ContentControl.Content、TextBox.Header,那样就须求四个能源,形成了冗余,而大气的冗余最后会产生错误。

    总之,那一个当地化方案有众多主题素材,即便这些方案是微软引进的。既然是微软推举的,应该是永葆最棒的,只怕是作者的用法不对?

    接下去在此个方案的功底上做些退换,希望能够让本地化更加好用。

    3. 动态切换语言

    不是我太执着动态切换语言,是体验师真的心仪这些效果,因为不用重启应用就能够测量检验到持有语言的UI。

    UWP提供了ApplicationLanguages.PrimaryLanguageOverride属性用于转移语言首要推荐项,即能够变动使用的言语,用法如下:

    Windows.Globalization.ApplicationLanguages.PrimaryLanguageOverride = "zh-CN";
    

    那几个更动是永世的,但不会对如今UI及片段系列组件生效,只会影响未来创制的UI成分。修正ApplicationLanguages.PrimaryLanguageOverride,会异步地接触ResourceContext.QualifierValues的MapChanged事件,可以监听这一个事件并更新UI。那样就可以完成轻松的动态切换语言效能。

    DynamicResources.cs

    public class DynamicResources : INotifyPropertyChanged
    {
        public DynamicResources()
        {
            _defaultContextForCurrentView = ResourceContext.GetForCurrentView();
    
            _defaultContextForCurrentView.QualifierValues.MapChanged += async (s, m) =>
            {
                await MainPage.Current.Dispatcher.RunAsync(Windows.UI.Core.CoreDispatcherPriority.Normal, () =>
                {
                    OnPropertyChanged("");
                });
            };
        }
    
        private ResourceContext _defaultContextForCurrentView;
    
        public string Main
        {
            get { return ResourceManager.Current.MainResourceMap.GetValue("DynamicResources/Main", _defaultContextForCurrentView).ValueAsString; }
        }
    
        public string Settings
        {
    
            get { return ResourceManager.Current.MainResourceMap.GetValue("DynamicResources/Settings", _defaultContextForCurrentView).ValueAsString; }
        }
    
        public string RestartNote
        {
            get { return ResourceManager.Current.MainResourceMap.GetValue("DynamicResources/RestartNote", _defaultContextForCurrentView).ValueAsString; }
        }
    
        public event PropertyChangedEventHandler PropertyChanged;
    
        [NotifyPropertyChangedInvocator]
        protected virtual void OnPropertyChanged([CallerMemberName] string propertyName = null)
        {
            PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
        }
    }
    

    SettingView.xaml

    <Page.Resources>
        <local:DynamicResources x:Key="DynamicResources"/>
    </Page.Resources>
    <Grid Background="{ThemeResource ApplicationPageBackgroundThemeBrush}">
        <StackPanel>
            <ListView x:Name="LanguageListView" Margin="10">
                <ListViewItem Tag="zh-Hans-CN" Content="中文"/>
                <ListViewItem Tag="en-US" Content="English"/>
            </ListView>
            <TextBlock x:Name="NoteElement" Foreground="#FFF99F00" Margin="20,10" Visibility="Collapsed"
                       Text="{Binding RestartNote,Source={StaticResource DynamicResources}}"
                       />
        </StackPanel>
    </Grid>
    

    SettingView.xaml.cs

    private async void OnLanguageListViewSelectionChanged(object sender, SelectionChangedEventArgs e)
    {
        var item = LanguageListView.SelectedItem as ListViewItem;
        if (item == null)
            return;
    
        ApplicationLanguages.PrimaryLanguageOverride = item.Tag as string;
        _hasChangedLanguage = true;
        await Dispatcher.RunAsync(CoreDispatcherPriority.Normal, ShowNoteElement);
    }
    
    private void ShowNoteElement()
    {
        NoteElement.Visibility = Visibility.Visible;
        var appView = Windows.UI.ViewManagement.ApplicationView.GetForCurrentView();
        appView.Title = (LanguageListView.SelectedItem as ListViewItem)?.Content as string;
    }
    

    图片 7

    只在装置页面及菜单那一个在切换语言时不会重复加载的UI上使用Binding,此外地点不改变,那样简单的动态切换语言就兑现了。运营结果如上,能够见到TextBox右键菜单仍未切换语言,要求重新起动。

    UWP默许只安装计算机对应的语言,那样能够节约安装空间,但影响到动态切换语言的功用,要消灭那个主题素材得以参见以下内容(作者没有注脚过卡塔尔国:[localization

    • How to always install all localized resources in Windows Store UWP app
    • Stack Overflow]() 。

    4. 赢得完全的规划视图

    在Fall Creators Update早前为了博取设计时视图能够选拔索引器。很罕有空子在C#中用到索引器,XAML中也非常少用到Binding到字符串索引的语法,就是那四个效率在本地化中帮了大忙。

    public class ResourcesStrings
    {
        public string this[string key]
        {
            get
            {
                return ResourceLoader.GetForViewIndependentUse().GetString(key);
            }
        }
    }
    
    <Page.Resources>
        <local:ResourcesStrings x:Key="S"/>
    </Page.Resources>
    <Grid Background="{ThemeResource ApplicationPageBackgroundThemeBrush}">
            <TextBlock Text="{Binding Source={StaticResource S},Path=[MainTitle]}" />
    </Grid>
    

    图片 8

    只须要这么写就能够得到完整的设计时试图,不过照旧还未清除智能感知和错误提醒那七个问题。

    在这里个方案上也可粗略地完结动态切换语言。

    public class ApplicationResources : INotifyPropertyChanged
    {
        public ApplicationResources()
        {
            DynamicResources = new DynamicResourcesStrings();
            Resources = new ResourcesStrings();
            Current = this;
        }
    
        public static ApplicationResources Current { get; private set; }
    
        public event PropertyChangedEventHandler PropertyChanged;
    
        public DynamicResourcesStrings DynamicResources { get; }
    
        public ResourcesStrings Resources { get; }
    
        public string Language
        {
            get
            {
                return ApplicationLanguages.PrimaryLanguageOverride;
            }
            set
            {
    
                if (ApplicationLanguages.PrimaryLanguageOverride == value)
                    return;
    
                ApplicationLanguages.PrimaryLanguageOverride = value;
                if (MainPage.Current != null )
                    MainPage.Current.Dispatcher.RunAsync(CoreDispatcherPriority.Normal, () => { OnPropertyChanged(""); });
            }
        }
    
        [NotifyPropertyChangedInvocator]
        protected virtual void OnPropertyChanged([CallerMemberName] string propertyName = null)
        {
            PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
        }
    }
    
    <ListViewItem Content="{Binding Source={StaticResource R},Path=DynamicResources[Main]}"/>
    

    不清楚为什么,在VisualStudio上间或不能拿到设计时视图,全数文字都来得为"Item"。

    5. 使用resx财富文件

    既然UWP是XAML大家族的大器晚成份子,那么应该也足以行使resx能源文件贯彻当地化,究竟生成resx对应代码的是PublicResXFileCodeGenerator,并非UWP本人。

    1. 展开“加多新项”对话框,选中“财富文件(.resw卡塔尔国”,在“名称”文本框少校文件名称改为“Labels.resx”,点击“增多”。
    2. 在“解决方案能源微电脑”选中“Labels.resx”,邮件展开“属性”视图,“生成操作”选拔“嵌入的能源”。
    3. 将“Labels.resx”复制为“Labels.zh-CN.resx”,张开“Labels.zh-CN.resx”,“访谈修饰符”改为“无代码生成”。
    4. 在“AssemblyInfo.cs”加多如下代码:

      [assembly: NeutralResourcesLanguage("en-US")]
      

    那样就可以在UWP中采纳resx财富文件了。达成本地化的代码和上意气风发篇作品中介绍的WPF当地化方案大致。

    public class ApplicationResources : INotifyPropertyChanged
    {
        public static ApplicationResources Current { get; private set; }
    
        public ApplicationResources()
        {
            Labels = new Labels();
            if (string.IsNullOrWhiteSpace(ApplicationLanguages.PrimaryLanguageOverride) == false)
                Language = ApplicationLanguages.PrimaryLanguageOverride;
            else
                Language = Windows.System.UserProfile.GlobalizationPreferences.Languages.FirstOrDefault();
    
            Current = this;
        }
    
        public Labels Labels { get; set; }
    
        public event PropertyChangedEventHandler PropertyChanged;
    
        public virtual void OnPropertyChanged([CallerMemberName] string propertyName = null)
        {
            PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
    
        }
    
        private string _language;
    
        /// <summary>
        /// 获取或设置 Language 的值
        /// </summary>
        public string Language
        {
            get { return _language; }
            set
            {
                if (_language == value)
                    return;
    
                _language = value;
                Labels.Culture = new System.Globalization.CultureInfo(_language);
                ApplicationLanguages.PrimaryLanguageOverride = _language;
                OnPropertyChanged("");
            }
        }
    }
    

    采纳体验和WPF中的resx本地化方案差不离,设计时援助差非常的少全盘,富含智能感知和谬误提醒,可是如故不可能清除系统组件中的本地化难点(如TextBox右键菜单)。此外,编译时会报错:带有输出类型“appcontainerexe”的档案的次序不帮助生成操作“EmbeddedResource”。解决方案是不在UWP应用类型中增添resx能源文件,而在类库中增加resx财富文件,那样连错误都不报了。

    不精晓Xamarin.Forms是否也足以如此达成,究竟它也是XAML大家族的风姿罗曼蒂克员。

    6. 结语

    商讨了如此多resw财富文件的方案,结果要么resx财富文件用得最顺手,终究那么些方案小编早就用了重重年(在silverlight中必须要用这几个方案)。具体运用哪个方案不一致。

    急需重申的是resx并不能够一心代表resw方案,超多时候须要混合使用,举例使用的Display Name能够运用resw轻易达成本地化:
    图片 9

    本地化的主旨依然有这多少个剧情,这篇作品只策画介绍入门知识,更浓烈的学识能够参见上边给出的链接。

    7. 参考

    Guidelines for globalization - UWP app developer Microsoft Docs
    Localize strings in your UI and app package manifest - UWP app developer Microsoft Docs
    Load images and assets tailored for scale, theme, high contrast, and others - UWP app developer Microsoft Docs
    敏捷入门:翻译 UI 财富(XAML卡塔尔国
    c# - UWP Resource file for languages is not deployed correctly - Stack Overflow
    localization - How to always install all localized resources in Windows Store UWP app - Stack Overflow
    Win10 UWP 开垦种类:使用多语言工具包让应用支撑多语言 - yan_xiaodi - 博客园
    Windows 10 Apps Designing for Global Customers

    8. 源码

    GitHub - LocalizationDemo

    本文由澳门新葡萄京最大平台发布于www.4996.com,转载请注明出处:本地化入门

    关键词: