资源和代码Resources and Code

本概述主要介绍如何使用代码(而非 可扩展应用程序标记语言 (XAML)Extensible Application Markup Language (XAML) 语法)来访问或创建 Windows Presentation Foundation (WPF)Windows Presentation Foundation (WPF) 资源。This overview concentrates on how Windows Presentation Foundation (WPF)Windows Presentation Foundation (WPF) resources can be accessed or created using code rather than 可扩展应用程序标记语言 (XAML)Extensible Application Markup Language (XAML) syntax. 有关常规资源用法以及 XAMLXAML 语法角度的资源的详细信息,请参阅 XAML 资源For more information on general resource usage and resources from a XAMLXAML syntax perspective, see XAML Resources.

从代码访问资源Accessing Resources from Code

用于识别通过 XAMLXAML 定义的资源的键也用于检索特定资源(如果你在代码中请求此资源)。The keys that identify resources if they are defined through XAMLXAML are also used to retrieve specific resources if you request the resource in code. 从代码检索资源的最简单方法是调用FindResourceTryFindResource从应用程序中的框架级对象的方法。The simplest way to retrieve a resource from code is to call either the FindResource or the TryFindResource method from framework-level objects in your application. 这两个方法之间的行为差异在于当未找到所请求的键时所发生的情况。The behavioral difference between these methods is what happens if the requested key is not found. FindResource 引发了异常;TryFindResource不会引发异常,而是返回nullFindResource raises an exception; TryFindResource will not raise an exception but returns null. 每个方法都将资源键作为一个输入参数,并返回一个松散类型化对象。Each method takes the resource key as an input parameter, and returns a loosely typed object. 资源键通常是字符串,但有时也用作非字符串;有关详细信息,请参阅将对象用作键部分。Typically, a resource key is a string, but there are occasional nonstring usages; see the Using Objects as Keys section for details. 通常应将返回的对象强制转换为请求资源时设置的属性所要求的类型。Typically you would cast the returned object to the type required by the property that you are setting when requesting the resource. 代码资源解析的查找逻辑与动态资源引用 XAMLXAML 情况相同。The lookup logic for code resource resolution is the same as the dynamic resource reference XAMLXAML case. 对资源的搜索从调用元素开始,然后继续搜索逻辑树中的后续父元素。The search for resources starts from the calling element, then continues to successive parent elements in the logical tree. 如果必要,将继续查找应用程序资源、主题以及系统资源。The lookup continues onwards into application resources, themes, and system resources if necessary. 资源的代码请求将正确地说明资源字典(可能排在从 XAMLXAML 加载的资源字典之后)中的运行时更改,也将说明实时系统资源更改。A code request for a resource will properly account for runtime changes in resource dictionaries that might have been made subsequent to that resource dictionary being loaded from XAMLXAML, and also for realtime system resource changes.

以下是一个简短的代码示例,通过键查找资源,并使用返回的值来设置属性,作为实现Click事件处理程序。The following is a brief code example that finds a resource by key and uses the returned value to set a property, implemented as a Click event handler.

void SetBGByResource(object sender, RoutedEventArgs e)
{
  Button b = sender as Button;
  b.Background = (Brush)this.FindResource("RainbowBrush");
}
Private Sub SetBGByResource(ByVal sender As Object, ByVal e As RoutedEventArgs)
  Dim b As Button = TryCast(sender, Button)
  b.Background = CType(Me.FindResource("RainbowBrush"), Brush)
End Sub

将分配的资源引用的一种替代方法是SetResourceReferenceAn alternative method for assigning a resource reference is SetResourceReference. 该方法采用两个参数:资源的键,以及特定依赖属性(应向其分配资源值的元素实例上的依赖属性)的标识符。This method takes two parameters: the key of the resource, and the identifier for a particular dependency property that is present on the element instance to which the resource value should be assigned. 就功能而言,此方法是相同的,且具有无需强制转换任何返回值的优点。Functionally, this method is the same and has the advantage of not requiring any casting of return values.

仍另一种方法以编程方式访问资源访问的内容是Resources作为字典的属性。Still another way to access resources programmatically is to access the contents of the Resources property as a dictionary. 通过访问该属性包含的字典,还可以向现有集合添加新资源、检查集合中是否已经存在给定的键名称以及执行其他字典/集合操作。Accessing the dictionary contained by this property is also how you can add new resources to existing collections, check to see if a given key name is already taken in the collection, and other dictionary/collection operations. 如果你正在编写WPFWPF完全在代码中的应用程序,您还可以创建整个集合在代码中,将密钥分配给它,,然后将分配到的已完成的集合Resources建立的元素的属性。If you are writing a WPFWPF application entirely in code, you can also create the entire collection in code, assign keys to it, and then assign the finished collection to the Resources property of an established element. 这将在下一部分介绍。This will be described in the next section.

你可以在任何给定索引Resources集合,并为该索引,但你使用特定密钥应注意访问这种方式中的资源未遵循资源解析的正常运行时规则。You can index within any given Resources collection, using a specific key as the index, but you should be aware that accessing the resource in this way does not follow the normal runtime rules of resource resolution. 你访问的仅是该特定集合。You are only accessing that particular collection. 如果在请求的键处未找到有效的对象,则资源查找将不会遍历范围直至根或应用程序。Resource lookup will not be traversing the scope to the root or the application if no valid object was found at the requested key. 但是,在某些情况下,正因为对键的搜索范围进行了更多的约束,才使得此方法在性能上具有优势。However, this approach may have performance advantages in some cases precisely because the scope of the search for the key is more constrained. 请参阅ResourceDictionary如何直接使用的资源字典的更多详细信息的类。See the ResourceDictionary class for more details on how to work with the resource dictionary directly.

使用代码创建资源Creating Resources with Code

如果要通过代码方式创建整个 WPFWPF 应用程序,可能也需要通过代码方式创建该应用程序中的任何资源。If you want to create an entire WPFWPF application in code, you might also want to create any resources in that application in code. 若要实现此目的,创建一个新ResourceDictionary实例,并将所有资源添加到字典使用连续调用ResourceDictionary.AddTo achieve this, create a new ResourceDictionary instance, and then add all the resources to the dictionary using successive calls to ResourceDictionary.Add. 然后,使用ResourceDictionary因此创建设置Resources位于页范围内的元素上的属性或Application.ResourcesThen, use the ResourceDictionary thus created to set the Resources property on an element that is present in a page scope, or the Application.Resources. 此外可以维护ResourceDictionary作为独立对象,而无需将其添加到元素。You could also maintain the ResourceDictionary as a standalone object without adding it to an element. 但是,如果这样做,必须通过项键来访问其中的资源,就好像它是泛型字典一样。However, if you do this, you must access the resources within it by item key, as if it were a generic dictionary. 一个ResourceDictionary,它未附加到元素Resources属性将不存在元素树的一部分并可供查找序列中没有作用域FindResource和相关方法。A ResourceDictionary that is not attached to an element Resources property would not exist as part of the element tree and has no scope in a lookup sequence that can be used by FindResource and related methods.

将对象用作键Using Objects as Keys

大多数资源用法都会将资源的键设置为字符串。Most resource usages will set the key of the resource to be a string. 但是,各个 WPFWPF 功能都特意不使用字符串类型来指定键,而是将此参数设置为对象。However, various WPFWPF features deliberately do not use a string type to specify keys, instead this parameter is an object. WPFWPF 样式和主题支持使用按对象对资源进行键控的功能。The capability of having the resource be keyed by an object is used by the WPFWPF style and theming support. 主题中成为否则非样式的控件的默认样式的样式来进行键控的Type它们应当应用于的控件。The styles in themes which become the default style for an otherwise non-styled control are each keyed by the Type of the control that they should apply to. 按类型进行键控提供了一种可靠的查找机制,该机制作用于每个控件类型的默认实例,即使派生类型不具有默认样式,也可以通过反射检测到类型,并将类型用于设置派生类的样式。Being keyed by type provides a reliable lookup mechanism that works on default instances of each control type, and type can be detected by reflection and used for styling derived classes even though the derived type otherwise has no default style. 您可以指定Type密钥对中定义的资源XAMLXAML通过使用X:type 标记扩展You can specify a Type key for a resource defined in XAMLXAML by using the x:Type Markup Extension. 对于支持 WPFWPF 功能的其他非字符串键用法,也存在类似扩展,如 ComponentResourceKey 标记扩展Similar extensions exist for other nonstring key usages that support WPFWPF features, such as ComponentResourceKey Markup Extension.

请参阅See also