• WPF入门(4)——资源


    引用《深入浅出WPF》对资源的解读:

    每个WPF的界面元素都具有一个名为Resources的属性,这个属性继承自FrameworkElement类,其类型为ResourceDictionary。ResourceDictionary能够以“键-值”对的形式存储资源(注:可以是实例,如一个类的实例;也可以是基本类型如字符串),当需要使用某个资源时,使用“键-值”对可以索引到资源对象。
    ——刘铁猛.深入浅出WPF(Kindle位置2580-2582).中国水利水电出版社.Kindle版本.

    wpf的资源字典是FrameworkElement的一个字段,任何继承自FrameworkElement的类都拥有该属性。
    我们可以把一些实例对象保存到资源字典中,为之设置一个key,当使用这些对象的时候直接在xaml中<Button Style="{StaticResource TransparentButton}">即可。TransparentButton就是保存在资源字典中的实例对象。

    有一点要注意,public class Application : DispatcherObject, IHaveResources, IQueryAmbient,这个application类也有自己的资源字典属性,它并不是继承自FrameworkElement。

    简单的资源使用

    参考 https://www.cnblogs.com/zhili/p/WPFResourceAndStyle.html
    下面的示例为window添加了资源字典。

    <Window x:Class="ResourceDemo.ResourceUse"
            xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
            xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
            Title="REsource" Height="100" Width="350"
            xmlns:sys="clr-namespace:System;assembly=mscorlib">
        <Window.Resources>
            <!--定义一个字符串资源-->
            <sys:String x:Key="nameStr">
                LearningHard博客:http://www.cnblogs.com/zhili/
            </sys:String>
        </Window.Resources>
        <StackPanel>
            <!--通过资源key来对资源进行使用-->
            <TextBlock Text="{StaticResource nameStr}" Margin="10"/>
        </StackPanel>
    </Window>
    

    这样使用没什么难度,动态资源与静态资源这里也不赘述。

    资源字典

    下面的示例为Application类添加了资源字典,他是全局的,所有该应用下的类都能使用,如下面的示例

        <Application.Resources>
            <ResourceDictionary>
                <!--ResourceDictionary的MergedDictionaries属性是个集合,资源字典的集合,这里面的每一个元素都是一个资源字典-->
                <ResourceDictionary.MergedDictionaries>
                    <!--这里就指定了一些资源字典添加到MergedDictionaries集合中,这些被添加的资源字典都作为Application对象的资源字典使用,可以直接用每个字典中的key引用字典中与之对应的实例-->
                    <ResourceDictionary Source="/Resources/Str.xaml"/>
                    <ResourceDictionary Source="/Themes/ControlStyle.xaml"/>
                    <ResourceDictionary Source="/Resources/Colors.xaml"/>
                </ResourceDictionary.MergedDictionaries>          
            </ResourceDictionary>
        </Application.Resources>
    

    msdn解释:
    MergedDictionaries
    获取 ResourceDictionary 字典的集合,这些字典构成了合并字典中的各种资源字典。

    MergeDictionaries中每一个字典与字典之间的key可以重复。
    典型应用是全球化。
    https://docs.microsoft.com/zh-cn/dotnet/framework/wpf/advanced/wpf-globalization-and-localization-overview
    https://www.bbsmax.com/A/gGdXAWPQz4/

    以ScreenToGit项目为例,作者做国际化就是定义了n种语言实现的字符串:

    切换语言的时候实际上是切换资源字典,代码则完全不用修改。

    下面的代码是摘抄自ScreenToGif的StringResources.zh.xaml文件

    <ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
                        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
                        xmlns:s="clr-namespace:System;assembly=mscorlib"
                        xml:space="preserve">
        
        <!--To use a new line: &#x0d;-->
        <!--Or CarriageReturn + NewLine: &#x0d;&#x0a; or &#10;--> 
        <!--Special texts like {0}, are place holders for dynamic values, such as numbers.-->
        
        <!--General-->
        <s:String x:Key="Ok">确定</s:String>
        <s:String x:Key="Back">返回</s:String>
        <s:String x:Key="Cancel">取消</s:String>
        <s:String x:Key="Yes">是</s:String>
        <s:String x:Key="No">否</s:String>
        <s:String x:Key="Frame">帧</s:String>
        <s:String x:Key="Suppress">隐藏</s:String>
        <s:String x:Key="Preview">预览</s:String>
        <s:String x:Key="S.Add">添加</s:String>
        <s:String x:Key="S.Edit">编辑</s:String>
        <s:String x:Key="S.Id">标识</s:String>
        <s:String x:Key="S.Title">标题</s:String>
        <s:String x:Key="S.Description">描述</s:String>
        <s:String x:Key="S.SelectColor">单击此处选择颜色。</s:String>
    </ResourceDictionary>
    

    使用方式(同样摘自ScreenToGif):

    <!--Options-->
    <StackPanel Grid.Row="0" Grid.Column="0" Grid.RowSpan="2" x:Name="OptionsStackPanel" Margin="0" MaxWidth="180">
    	<n:ImageRadioButton x:Name="AppRadio" Text="{DynamicResource Application}" Content="{StaticResource Vector.Application}" TextWrapping="WrapWithOverflow" IsChecked="True"
    						Padding="1,3,5,3" FontSize="17" FontFamily="Segoe UI Semilight" Cursor="Hand" MaxSize="24" HorizontalContentAlignment="Left"/>
    	<n:ImageRadioButton x:Name="InterfaceRadio" Text="{DynamicResource Interface}" Content="{StaticResource Vector.Colors}" TextWrapping="WrapWithOverflow"
    						Padding="1,3,5,3" FontSize="17" FontFamily="Segoe UI Semilight" Cursor="Hand" MaxSize="24" HorizontalContentAlignment="Left"/>
    	<n:ImageRadioButton x:Name="AutomaticRadio" Text="{DynamicResource S.AutoTasks}" Content="{StaticResource Vector.Encoder}" TextWrapping="WrapWithOverflow"
    						Padding="1,3,5,3" FontSize="17" FontFamily="Segoe UI Semilight" Cursor="Hand" MaxSize="24" HorizontalContentAlignment="Left"/>
    	<n:ImageRadioButton x:Name="ShortcutsRadio" Text="{DynamicResource S.Shortcuts}" Content="{StaticResource Vector.Keyboard}" TextWrapping="Wrap"
    						Padding="1,3,5,3" FontSize="17" FontFamily="Segoe UI Semilight" Cursor="Hand" MaxSize="24" HorizontalContentAlignment="Left"/>
    	<n:ImageRadioButton x:Name="LanguageRadio" Text="{DynamicResource Language}" Content="{StaticResource Vector.Translate}"  TextWrapping="Wrap"
    						Padding="1,3,5,3" FontSize="17" FontFamily="Segoe UI Semilight" Cursor="Hand" MaxSize="24" HorizontalContentAlignment="Left"/>
    	<n:ImageRadioButton x:Name="TempRadio" Text="{DynamicResource TemporaryFiles}" Content="{StaticResource Vector.Temporary}" TextWrapping="Wrap"
    						Padding="1,3,5,3" FontSize="17" FontFamily="Segoe UI Semilight" Cursor="Hand" MaxSize="24" HorizontalContentAlignment="Left"/>
    	<n:ImageRadioButton x:Name="CloudRadioButton" Text="{DynamicResource Clouds}" Content="{StaticResource Vector.Web}" TextWrapping="Wrap"
    						Padding="1,3,5,3" FontSize="17" FontFamily="Segoe UI Semilight" Cursor="Hand" MaxSize="24" HorizontalContentAlignment="Left"/>
    	<n:ImageRadioButton x:Name="ExtrasRadioButton" Text="{DynamicResource Extras}" Content="{StaticResource Vector.Extras}" TextWrapping="Wrap"
    						Padding="1,3,5,3" FontSize="17" FontFamily="Segoe UI Semilight" Cursor="Hand" MaxSize="24" HorizontalContentAlignment="Left"/>
    	<n:ImageRadioButton x:Name="DonateRadio" Text="{DynamicResource Donate}" Content="{StaticResource Vector.Money}" TextWrapping="Wrap"
    						Padding="1,3,5,3" FontSize="17" FontFamily="Segoe UI Semilight" Cursor="Hand" MaxSize="24" HorizontalContentAlignment="Left"/>
    	<n:ImageRadioButton x:Name="AboutRadio" Text="{DynamicResource About}" Content="{StaticResource Vector.Info}"  TextWrapping="Wrap"
    						Padding="1,3,5,3" FontSize="17" FontFamily="Segoe UI Semilight" Cursor="Hand" MaxSize="24" HorizontalContentAlignment="Left"/>
    </StackPanel>
    

    最后附上ScreenToGif切换字典的函数:

    public static void SelectCulture(string culture)
    {
    	#region Validation
    
    	//If none selected, fallback to english.
    	if (string.IsNullOrEmpty(culture))
    		culture = "en";
    
    	if (culture.Equals("auto") || culture.Length < 2)
    	{
    		var ci = CultureInfo.InstalledUICulture;
    		culture = ci.Name;
    	}
    
    	#endregion
    
    	//Copy all MergedDictionarys into a auxiliar list.
    	var dictionaryList = Application.Current.Resources.MergedDictionaries.ToList();
    
    	#region Selected Culture
    
    	//Search for the specified culture.
    	var requestedCulture = $"/Resources/Localization/StringResources.{culture}.xaml";
    	var requestedResource = dictionaryList.FirstOrDefault(d => d.Source?.OriginalString == requestedCulture);
    
    	#endregion
    
    	#region Generic Branch Fallback
    
    	//Fallback to a more generic version of the language. Example: pt-BR to pt.
    	while (requestedResource == null && !string.IsNullOrEmpty(culture))
    	{
    		culture = CultureInfo.GetCultureInfo(culture).Parent.Name;
    		requestedCulture = $"/Resources/Localization/StringResources.{culture}.xaml";
    		requestedResource = dictionaryList.FirstOrDefault(d => d.Source?.OriginalString == requestedCulture);
    	}
    
    	#endregion
    
    	#region English Fallback
    
    	//If not present, fall back to english.
    	if (requestedResource == null)
    	{
    		culture = "en";
    		requestedCulture = "/Resources/Localization/StringResources.en.xaml";
    		requestedResource = dictionaryList.FirstOrDefault(d => d.Source?.OriginalString == requestedCulture);
    	}
    
    	#endregion
    
    	//If we have the requested resource, remove it from the list and place at the end.
    	//Then this language will be our current string table.
    	Application.Current.Resources.MergedDictionaries.Remove(requestedResource);
    	Application.Current.Resources.MergedDictionaries.Add(requestedResource);
    
    	//Inform the threads of the new culture.
    	Thread.CurrentThread.CurrentCulture = new CultureInfo(culture);
    	Thread.CurrentThread.CurrentUICulture = new CultureInfo(culture);
    
    	#region English Fallback of the Current Language
    
    	//Only non-English resources need a fallback, because the English resource is evergreen. TODO
    	if (culture.StartsWith("en"))
    		return;
    
    	var englishResource = dictionaryList.FirstOrDefault(d => d.Source?.OriginalString == "/Resources/Localization/StringResources.en.xaml");
    
    	if (englishResource != null)
    	{
    		Application.Current.Resources.MergedDictionaries.Remove(englishResource);
    		Application.Current.Resources.MergedDictionaries.Insert(Application.Current.Resources.MergedDictionaries.Count - 1, englishResource);
    	}
    
    	#endregion
    
    	GC.Collect(0);
    
    	if (!UserSettings.All.CheckForTranslationUpdates)
    		return;
    
    	//Async, fire and forget.
    	Task.Factory.StartNew(() => CheckForUpdates(culture));
    }
    

    一个示例

    工程上传到github :https://github.com/feipeng8848/WPF-Demo

  • 相关阅读:
    简明Python3教程 12.问题解决
    简明Python3教程 11.数据结构
    【SPOJ 694】Distinct Substrings
    【codeforces Manthan, Codefest 17 C】Helga Hufflepuff's Cup
    【CF Manthan, Codefest 17 B】Marvolo Gaunt's Ring
    【CF Manthan, Codefest 17 A】Tom Riddle's Diary
    【SPOJ 220】 PHRASES
    【POJ 3261】Milk Patterns
    【POJ 3294】Life Forms
    【POJ 1226】Substrings
  • 原文地址:https://www.cnblogs.com/feipeng8848/p/12072325.html
Copyright © 2020-2023  润新知