原文:Freezable 对象概述 | Microsoft Docs

Freezable 对象概述Freezable Objects Overview

  • 2017/03/30

本主题介绍如何有效地使用和创建 Freezable 对象,这些对象提供有助于提高应用程序性能的特殊功能。This topic describes how to effectively use and create Freezable objects, which provide special features that can help improve application performance. 被冻结对象的示例包括画笔、笔、转换、几何图形和动画。Examples of freezable objects include brushes, pens, transformations, geometries, and animations.

什么是可冻结的?What Is a Freezable?

Freezable 是一种特殊类型的对象,该对象具有两种状态:未冻结和已冻结。A Freezable is a special type of object that has two states: unfrozen and frozen. 解冻后,Freezable 的行为与任何其他对象的行为类似。When unfrozen, a Freezable appears to behave like any other object. 冻结后,不能再修改 Freezable。When frozen, a Freezable can no longer be modified.

Freezable 提供 Changed 事件来通知观察者对对象的任何修改。A Freezable provides a Changed event to notify observers of any modifications to the object. 冻结 Freezable 可以提高其性能,因为它不再需要在更改通知上消耗资源。Freezing a Freezable can improve its performance, because it no longer needs to spend resources on change notifications. 还可以在线程之间共享冻结的 Freezable,而未冻结的 Freezable 不能。A frozen Freezable can also be shared across threads, while an unfrozen Freezable cannot.

尽管 Freezable 类有许多应用程序,但 Windows Presentation Foundation (WPF)Windows Presentation Foundation (WPF) 中的大多数 Freezable 对象都与图形子系统相关。Although the Freezable class has many applications, most Freezable objects in Windows Presentation Foundation (WPF)Windows Presentation Foundation (WPF) are related to the graphics sub-system.

使用 Freezable 类可以更轻松地使用特定图形系统对象,并且可以帮助提高应用程序性能。The Freezable class makes it easier to use certain graphics system objects and can help improve application performance. 继承自 Freezable 的类型的示例包括 BrushTransformGeometry 类。Examples of types that inherit from Freezable include the Brush, Transform, and Geometry classes. 由于它们包含非托管资源,因此,系统必须监视这些对象进行修改,然后在对原始对象进行更改时更新其相应的非托管资源。Because they contain unmanaged resources, the system must monitor these objects for modifications, and then update their corresponding unmanaged resources when there is a change to the original object. 即使您不实际修改图形系统对象,系统仍必须将它的一些资源用于监视对象,以防您这样做更改。Even if you don't actually modify a graphics system object, the system must still spend some of its resources monitoring the object, in case you do change it.

例如,假设您创建一个 SolidColorBrush 画笔,并使用它来绘制按钮的背景。For example, suppose you create a SolidColorBrush brush and use it to paint the background of a button.

C#

复制

Button myButton = new Button();
SolidColorBrush myBrush = new SolidColorBrush(Colors.Yellow);
myButton.Background = myBrush;
Dim myButton As New Button()
Dim myBrush As New SolidColorBrush(Colors.Yellow)
myButton.Background = myBrush

呈现按钮时,WPFWPF 图形子系统将使用您提供的信息来绘制一组像素来创建按钮的外观。When the button is rendered, the WPFWPF graphics sub-system uses the information you provided to paint a group of pixels to create the appearance of a button. 虽然您使用纯色画笔来说明如何绘制按钮,但您的纯色画笔实际上不会执行绘制操作。Although you used a solid color brush to describe how the button should be painted, your solid color brush doesn't actually do the painting. 图形系统会为按钮和画笔生成快速、低级别的对象,并且这些对象确实出现在屏幕上。The graphics system generates fast, low-level objects for the button and the brush, and it is those objects that actually appear on the screen.

如果要修改画笔,则必须重新生成这些低级别对象。If you were to modify the brush, those low-level objects would have to be regenerated. 可冻结的类可让画笔查找其相应的已生成低级别对象并在更改时更新这些对象。The freezable class is what gives a brush the ability to find its corresponding generated, low-level objects and to update them when it changes. 启用此功能后,画笔会被视为 "解冻"。When this ability is enabled, the brush is said to be "unfrozen."

可冻结的 Freeze 方法使您能够禁用此自我更新功能。A freezable's Freeze method enables you to disable this self-updating ability. 您可以使用此方法使画笔变为 "冻结" 或不可修改。You can use this method to make the brush become "frozen," or unmodifiable.

备注

并非每个可冻结的对象都可以冻结。Not every Freezable object can be frozen. 若要避免引发 InvalidOperationException,请检查可冻结对象的 CanFreeze 属性的值,以确定是否可以冻结该对象,然后再尝试将其冻结。To avoid throwing an InvalidOperationException, check the value of the Freezable object's CanFreeze property to determine whether it can be frozen before attempting to freeze it.

C#

复制

if (myBrush.CanFreeze)
{
// Makes the brush unmodifiable.
myBrush.Freeze();
}
If myBrush.CanFreeze Then
' Makes the brush unmodifiable.
myBrush.Freeze()
End If

当你不再需要修改可冻结的时,冻结它可提供性能优势。When you no longer need to modify a freezable, freezing it provides performance benefits. 如果在此示例中冻结了画笔,则图形系统将不再需要监视其更改。If you were to freeze the brush in this example, the graphics system would no longer need to monitor it for changes. 图形系统还可以进行其他优化,因为它知道画笔不会改变。The graphics system can also make other optimizations, because it knows the brush won't change.

备注

为方便起见,可冻结对象保持解冻,除非你显式冻结它们。For convenience, freezable objects remain unfrozen unless you explicitly freeze them.

使用可冻结对象Using Freezables

使用未冻结的可冻结对象与使用任何其他类型的对象类似。Using an unfrozen freezable is like using any other type of object. 在下面的示例中,将 SolidColorBrush 的颜色在用于绘制按钮背景后从黄色更改为红色。In the following example, the color of a SolidColorBrush is changed from yellow to red after it's used to paint the background of a button. 图形系统在幕后工作,在下次刷新屏幕时,自动将按钮从黄色更改为红色。The graphics system works behind the scenes to automatically change the button from yellow to red the next time the screen is refreshed.

C#

复制

Button myButton = new Button();
SolidColorBrush myBrush = new SolidColorBrush(Colors.Yellow);
myButton.Background = myBrush; // Changes the button's background to red.
myBrush.Color = Colors.Red;
Dim myButton As New Button()
Dim myBrush As New SolidColorBrush(Colors.Yellow)
myButton.Background = myBrush ' Changes the button's background to red.
myBrush.Color = Colors.Red

冻结冻结Freezing a Freezable

若要使 Freezable 成为不可修改的,请调用其 Freeze 方法。To make a Freezable unmodifiable, you call its Freeze method. 冻结包含可冻结对象的对象时,这些对象也会被冻结。When you freeze an object that contains freezable objects, those objects are frozen as well. 例如,如果您冻结 PathGeometry,则它包含的图形和段也将冻结。For example, if you freeze a PathGeometry, the figures and segments it contains would be frozen too.

如果满足以下任一条件,则无法冻结可冻结的:A Freezable can't be frozen if any of the following are true:

  • 它具有动画或数据绑定属性。It has animated or data bound properties.

  • 它包含动态资源设置的属性。It has properties set by a dynamic resource. (有关动态资源的详细信息,请参阅XAML 资源。)(See the XAML Resources for more information about dynamic resources.)

  • 它包含不能冻结 Freezable 子对象。It contains Freezable sub-objects that can't be frozen.

如果这些条件为 false,并且你不打算修改 Freezable,则应将其冻结,以获取之前所述的性能优势。If these conditions are false, and you don't intend to modify the Freezable, then you should freeze it to gain the performance benefits described earlier.

调用可冻结的 Freeze 方法后,将无法再修改它。Once you call a freezable's Freeze method, it can no longer be modified. 尝试修改冻结对象将导致引发 InvalidOperationException。Attempting to modify a frozen object causes an InvalidOperationException to be thrown. 下面的代码引发异常,因为我们尝试在冻结画笔之后修改画笔。The following code throws an exception, because we attempt to modify the brush after it's been frozen.

C#

复制


Button myButton = new Button();
SolidColorBrush myBrush = new SolidColorBrush(Colors.Yellow); if (myBrush.CanFreeze)
{
// Makes the brush unmodifiable.
myBrush.Freeze();
} myButton.Background = myBrush; try { // Throws an InvalidOperationException, because the brush is frozen.
myBrush.Color = Colors.Red;
}catch(InvalidOperationException ex)
{
MessageBox.Show("Invalid operation: " + ex.ToString());
}

Dim myButton As New Button()
Dim myBrush As New SolidColorBrush(Colors.Yellow) If myBrush.CanFreeze Then
' Makes the brush unmodifiable.
myBrush.Freeze()
End If myButton.Background = myBrush Try ' Throws an InvalidOperationException, because the brush is frozen.
myBrush.Color = Colors.Red
Catch ex As InvalidOperationException
MessageBox.Show("Invalid operation: " & ex.ToString())
End Try

若要避免引发此异常,可以使用 IsFrozen 方法来确定 Freezable 是否被冻结。To avoid throwing this exception, you can use the IsFrozen method to determine whether a Freezable is frozen.

C#

复制


Button myButton = new Button();
SolidColorBrush myBrush = new SolidColorBrush(Colors.Yellow); if (myBrush.CanFreeze)
{
// Makes the brush unmodifiable.
myBrush.Freeze();
} myButton.Background = myBrush; if (myBrush.IsFrozen) // Evaluates to true.
{
// If the brush is frozen, create a clone and
// modify the clone.
SolidColorBrush myBrushClone = myBrush.Clone();
myBrushClone.Color = Colors.Red;
myButton.Background = myBrushClone;
}
else
{
// If the brush is not frozen,
// it can be modified directly.
myBrush.Color = Colors.Red;
}

Dim myButton As New Button()
Dim myBrush As New SolidColorBrush(Colors.Yellow) If myBrush.CanFreeze Then
' Makes the brush unmodifiable.
myBrush.Freeze()
End If myButton.Background = myBrush If myBrush.IsFrozen Then ' Evaluates to true.
' If the brush is frozen, create a clone and
' modify the clone.
Dim myBrushClone As SolidColorBrush = myBrush.Clone()
myBrushClone.Color = Colors.Red
myButton.Background = myBrushClone
Else
' If the brush is not frozen,
' it can be modified directly.
myBrush.Color = Colors.Red
End If

在上面的代码示例中,使用 Clone 方法为冻结对象创建了一个可修改的副本。In the preceding code example, a modifiable copy was made of a frozen object using the Clone method. 下一部分更详细地讨论了克隆。The next section discusses cloning in more detail.

备注

由于无法对冻结的可冻结对象进行动画处理,因此当你尝试使用 Storyboard对它们进行动画处理时,动画系统将自动创建冻结 Freezable 对象的可修改复本。Because a frozen freezable cannot be animated, the animation system will automatically create modifiable clones of frozen Freezable objects when you try to animate them with a Storyboard. 若要消除克隆导致的性能开销,请在要对对象进行动画处理时使对象保持解冻。To eliminate the performance overhead caused by cloning, leave an object unfrozen if you intend to animate it. 有关利用情节提要进行动画处理的详细信息,请参阅情节提要概述。For more information about animating with storyboards, see the Storyboards Overview.

从标记冻结Freezing from Markup

若要冻结在标记中声明的 Freezable 对象,请使用 PresentationOptions:Freeze 特性。To freeze a Freezable object declared in markup, you use the PresentationOptions:Freeze attribute. 在下面的示例中,将 SolidColorBrush 声明为页资源并冻结。In the following example, a SolidColorBrush is declared as a page resource and frozen. 然后,将使用它来设置按钮的背景。It is then used to set the background of a button.

XAML

复制



    

"><Page
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:PresentationOptions="http://schemas.microsoft.com/winfx/2006/xaml/presentation/options"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
mc:Ignorable="PresentationOptions"> <Page.Resources> <!-- This resource is frozen. -->
<SolidColorBrush
x:Key="MyBrush"
PresentationOptions:Freeze="True"
Color="Red" />
</Page.Resources> <StackPanel> <Button Content="A Button"
Background="{StaticResource MyBrush}">
</Button> </StackPanel>
</Page>

若要使用 Freeze 属性,必须映射到 "演示选项命名空间: http://schemas.microsoft.com/winfx/2006/xaml/presentation/options"。To use the Freeze attribute, you must map to the presentation options namespace: http://schemas.microsoft.com/winfx/2006/xaml/presentation/options. 建议使用 PresentationOptions 前缀来映射此命名空间:PresentationOptions is the recommended prefix for mapping this namespace:

XAML

复制

xmlns:PresentationOptions="http://schemas.microsoft.com/winfx/2006/xaml/presentation/options"

由于并非所有 XAML 读取器都能识别此特性,因此建议使用mc:可忽略属性Presentation:Freeze 特性标记为可忽略:Because not all XAML readers recognize this attribute, it's recommended that you use the mc:Ignorable Attribute to mark the Presentation:Freeze attribute as ignorable:

XAML

复制

xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
mc:Ignorable="PresentationOptions"

有关详细信息,请参阅mc:忽略属性页。For more information, see the mc:Ignorable Attribute page.

"解冻""Unfreezing" a Freezable

一旦冻结,就永远不能修改或解冻 Freezable;但是,可以使用 CloneCloneCurrentValue 方法创建未冻结的克隆。Once frozen, a Freezable can never be modified or unfrozen; however, you can create an unfrozen clone using the Clone or CloneCurrentValue method.

在下面的示例中,按钮的背景是使用画笔设置的,然后该画笔会被冻结。In the following example, the button's background is set with a brush and that brush is then frozen. 使用 Clone 方法创建画笔的未冻结副本。An unfrozen copy is made of the brush using the Clone method. 将修改克隆,并使用它将按钮的背景从黄色更改为红色。The clone is modified and used to change the button's background from yellow to red.

C#

复制

Button myButton = new Button();
SolidColorBrush myBrush = new SolidColorBrush(Colors.Yellow); // Freezing a Freezable before it provides
// performance improvements if you don't
// intend on modifying it.
if (myBrush.CanFreeze)
{
// Makes the brush unmodifiable.
myBrush.Freeze();
} myButton.Background = myBrush; // If you need to modify a frozen brush,
// the Clone method can be used to
// create a modifiable copy.
SolidColorBrush myBrushClone = myBrush.Clone(); // Changing myBrushClone does not change
// the color of myButton, because its
// background is still set by myBrush.
myBrushClone.Color = Colors.Red; // Replacing myBrush with myBrushClone
// makes the button change to red.
myButton.Background = myBrushClone;
Dim myButton As New Button()
Dim myBrush As New SolidColorBrush(Colors.Yellow) ' Freezing a Freezable before it provides
' performance improvements if you don't
' intend on modifying it.
If myBrush.CanFreeze Then
' Makes the brush unmodifiable.
myBrush.Freeze()
End If myButton.Background = myBrush ' If you need to modify a frozen brush,
' the Clone method can be used to
' create a modifiable copy.
Dim myBrushClone As SolidColorBrush = myBrush.Clone() ' Changing myBrushClone does not change
' the color of myButton, because its
' background is still set by myBrush.
myBrushClone.Color = Colors.Red ' Replacing myBrush with myBrushClone
' makes the button change to red.
myButton.Background = myBrushClone

备注

不管使用哪种克隆方法,动画都不会复制到新的 Freezable。Regardless of which clone method you use, animations are never copied to the new Freezable.

CloneCloneCurrentValue 方法将生成具有该冻结的深层副本。The Clone and CloneCurrentValue methods produce deep copies of the freezable. 如果可冻结的包含其他冻结的可冻结对象,则它们也会被克隆,并可进行修改。If the freezable contains other frozen freezable objects, they are also cloned and made modifiable. 例如,如果克隆一个冻结的 PathGeometry 以使其可修改,则还会复制其包含的图形和线段,并使其成为可修改的。For example, if you clone a frozen PathGeometry to make it modifiable, the figures and segments it contains are also copied and made modifiable.

创建自己的有冻结类Creating Your Own Freezable Class

派生自 Freezable 的类获得以下功能。A class that derives from Freezable gains the following features.

  • 特殊状态:只读(冻结)和可写状态。Special states: a read-only (frozen) and a writable state.

  • 线程安全:可在线程之间共享冻结 Freezable。Thread safety: a frozen Freezable can be shared across threads.

  • 详细更改通知:与其他 DependencyObject不同,可冻结对象会在子属性值更改时提供更改通知。Detailed change notification: Unlike other DependencyObjects, Freezable objects provide change notifications when sub-property values change.

  • 轻松克隆:可冻结的类已经实现了几种生成深层克隆的方法。Easy cloning: the Freezable class has already implemented several methods that produce deep clones.

Freezable 是一种 DependencyObject类型,因此使用了依赖属性系统。A Freezable is a type of DependencyObject, and therefore uses the dependency property system. 类属性不一定是依赖属性,但使用依赖属性将减少您必须编写的代码量,因为 Freezable 类设计为具有依赖属性。Your class properties don't have to be dependency properties, but using dependency properties will reduce the amount of code you have to write, because the Freezable class was designed with dependency properties in mind. 有关依赖属性系统的详细信息,请参阅依赖属性概述。For more information about the dependency property system, see the Dependency Properties Overview.

每个 Freezable 子类必须重写 CreateInstanceCore 方法。Every Freezable subclass must override the CreateInstanceCore method. 如果你的类对所有数据使用依赖属性,则你已完成。If your class uses dependency properties for all its data, you're finished.

如果类包含非依赖属性数据成员,还必须重写以下方法:If your class contains non-dependency property data members, you must also override the following methods:

还必须遵守以下规则,以便访问和写入不是依赖属性的数据成员:You must also observe the following rules for accessing and writing to data members that are not dependency properties:

  • 在读取非依赖属性数据成员的任何 API 的开头,调用 ReadPreamble 方法。At the beginning of any API that reads non-dependency property data members, call the ReadPreamble method.

  • 在写入非依赖属性数据成员的任何 API 的开头,调用 WritePreamble 方法。At the beginning of any API that writes non-dependency property data members, call the WritePreamble method. (在 API 中调用 WritePreamble 后,如果还读取非依赖属性数据成员,则无需额外调用 ReadPreamble。)(Once you've called WritePreamble in an API, you don't need to make an additional call to ReadPreamble if you also read non-dependency property data members.)

  • 在退出写入非依赖属性数据成员的方法之前调用 WritePostscript 方法。Call the WritePostscript method before exiting methods that write to non-dependency property data members.

如果类包含 DependencyObject 对象的非依赖属性数据成员,则每次更改其值时,还必须调用 OnFreezablePropertyChanged 方法,即使要将成员设置为 null也是如此。If your class contains non-dependency-property data members that are DependencyObject objects, you must also call the OnFreezablePropertyChanged method each time you change one of their values, even if you're setting the member to null.

备注

使用对基实现的调用来开始每个 Freezable 方法,这一点非常重要。It's very important that you begin each Freezable method you override with a call to the base implementation.

有关自定义 Freezable 类的示例,请参阅自定义动画示例。For an example of a custom Freezable class, see the Custom Animation Sample.

请参阅See also

此页面有帮助吗?

还有其他反馈吗?

跳过
提交

谢谢。


Freezable 对象概述 | Microsoft Docs的更多相关文章

  1. [Windows] 在 Microsoft Docs 网站中挖掘 MVVM 的各种学习资源

    最近写了一些 MVVM 框架的文章,翻了一些 Microsoft Docs 的文档,顺便就对 MVVM 本身来了兴致,想看看更多当年相关的文档.在 MVVM 出现后十多年,我在不同的场合见到过多种 M ...

  2. Asp.net内置对象之Request对象(概述及应用)

    Request对象主要用于获取来自客户端的数据,如用户填入表单的数据.保存在客户端的Cookie等,本文将围绕Request对象,讲解其的主要作用:读取窗体变量.读取查询字符串变量.取得Web服务器端 ...

  3. Freezable 对象(WPF)

    # Freezable 对象(WPF) # > Freezable 继承自 DependencyObject,同时添加了 Freezable 方法,用于冻结对象. --- ## 冻结对象 ## ...

  4. Unit06: 外部对象概述 、 window 对象 、 document 对象

    Unit06: 外部对象概述 . window 对象 . document 对象 小代码演示: <!DOCTYPE html> <html> <head> < ...

  5. Unit05: JavaScript对象概述 、 常用内置对象一 、 常用内置对象二 、 常用内置对象三

    Unit05: JavaScript对象概述 . 常用内置对象一 . 常用内置对象二 . 常用内置对象三 常用内置对象使用演示: <!DOCTYPE html> <html> ...

  6. 开始使用 Docker (Linux 上运行 SQL Server) 上的 SQL Server 容器 - SQL Server | Microsoft Docs

    原文:开始使用 Docker (Linux 上运行 SQL Server) 上的 SQL Server 容器 - SQL Server | Microsoft Docs 快速入门:使用 Docker ...

  7. 指定程序集的位置 | Microsoft Docs

    原文:指定程序集的位置 | Microsoft Docs 指定程序集的位置Specifying an Assembly's Location 2017/03/30 作者 使用<b a s e & ...

  8. Kubernetes 中的核心组件与基本对象概述

    Kubernetes 是 Google 基于 Borg 开源的容器编排调度,用于管理容器集群自动化部署.扩容以及运维的开源平台.作为云原生计算基金会 CNCF(Cloud Native Computi ...

  9. JSP内置对象概述

    JSP内置对象预先定义了九个这个的对象: request(请求) . response (响应). session (会话). application (应用程序). out . pageContex ...

随机推荐

  1. AGC011-E Increasing Numbers

    题意 给定一个数\(n\),\(n≤10^{500,000}\),问\(n\)最少可以拆分成几个不降数的和.一个不降数是在十进制位下,从高位往低位看,每个数都不会比高位的数更小的数 做法 不降数可以拆 ...

  2. tomcat虚拟路径的配置方法

    方式一: 将web项目配置到webapps以外的目录 在conf/server.xml中配置,找到<host>标签,<Content docBase="E:\yqs\Jsp ...

  3. css3基础-文本与字体+转换+过渡+动画+案例

    Css3文本与字体   文本阴影 h1 { text-shadow: 5px 5px 5px red; } word-break换行: h1:nth-child(1) { word-break: no ...

  4. linux---基础学习

    学习使用linux 偶然间看到一篇介绍linux的使用,于是看了看,整体看完,虽然看的有些懵✒,但还是坚持看完了基础部分,并做了一些摘要. man页面所属的分类标识 常用的是分类1和分类3 (1).用 ...

  5. P1089题解 津津的储蓄计划

    来水一篇题解 #include <iostream> using namespace std; int main() { int month[12]; int mother=0,have= ...

  6. Mybatis Dao接口与Xml文件不匹配的问题:Invalid bound statement (not found)

    <!-- 如果不添加此节点mybatis的mapper.xml文件都会被漏掉. --> <resources> <resource> <directory&g ...

  7. 拦截器——原理(AOP、责任链模式、配置)

    1.Struts2拦截器概述: (1)Struts2框架封装中封装了很多功能,这些功能其实都是封装在Struts2的拦截器里面,Struts2里面有很多拦截器,每次不是这些拦截器都执行,每次只执行默认 ...

  8. 3、MapReduce详解与源码分析

    文章目录 1 Split阶段 2 Map阶段 2.1分区 2.2排序 3 Shuffle阶段 4 Reduce阶段 1 Split阶段      首先,接到hdf文件输入,在mapreduce中的ma ...

  9. GNU Radio无线通信嗅探基础

    文章内容简介 1.使用哪些grc模块完成我们的嗅探工作 2.如何选择参数以获取最完美的波形 3.如何从波形还原回数据 我接下来会使用电视棒(RTL-SDR)嗅探一个固定码遥控锁开发组件. 我使用如下的 ...

  10. 解决shell 报错:syntax error: unexpected end of file

    debug  shell:执行 sh -x test.sh vi test.sh :set fileformat=unix :wq解决问题原因是我在windows pycharm 写的格式不符合uni ...