zoukankan      html  css  js  c++  java
  • 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

  • 相关阅读:
    【瞎口胡】CDQ 分治
    题解 Luogu P2934 [USACO09JAN]Safe Travel G
    【瞎口胡】线段树优化建图
    git did not exit cleanly (exit code 128)如何解决
    转贴Linux服务器性能评估
    小记 SqlHelper
    zookeeper安装部署
    zookeeper原理介绍
    zookeeper基本操作
    zookeeper四字命令
  • 原文地址:https://www.cnblogs.com/feipeng8848/p/12072325.html
Copyright © 2011-2022 走看看