Общие сведения об объектах класса FreezableFreezable Objects Overview

В этом разделе описывается, как эффективно использовать и создавать Freezable объекты, которые предоставляют специальные функции, которые могут помочь повысить производительность приложения.This topic describes how to effectively use and create Freezable objects, which provide special features that can help improve application performance. Объекты freezable примеры кисти, перья, преобразования, геометрии и анимации.Examples of freezable objects include brushes, pens, transformations, geometries, and animations.

Что такое Freezable?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 класс имеет много приложений, наиболее Freezable объекты в Windows Presentation Foundation (WPF)Windows Presentation Foundation (WPF) связаны с графическая подсистема.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 включают Brush, Transform, и Geometry классы.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.

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. Класс freezable представляет, что дает возможность найти соответствующие объекты низкоуровневые и обновлять их при его изменении кисти.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."

Freezable 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.

Примечание

Не каждый объект Freezable может быть зафиксирован.Not every Freezable object can be frozen. Чтобы избежать возникновения InvalidOperationException, проверьте значение свойства объекта Freezable 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.

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

Если вам больше не нужно изменять freezable, зафиксировать этот дает выигрыш в производительности.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.

Примечание

Для удобства объекты freezable остаются незафиксированными, пока вы явным образом замораживайте.For convenience, freezable objects remain unfrozen unless you explicitly freeze them.

С помощью объектов FreezableUsing Freezables

Использование незафиксированного freezable аналогично использованию любого другого типа объекта.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.

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

Замораживание FreezableFreezing a Freezable

Чтобы сделать Freezable неизменяемым, необходимо вызвать его Freeze метод.To make a Freezable unmodifiable, you call its Freeze method. Когда вы закрепить объект, содержащий объекты freezable, эти объекты также закрепляются.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.

Freezable нельзя зафиксировать, если одно из следующих условий: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.

При вызове метода freezable 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.


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.


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.

Примечание поскольку зафиксированного freezable невозожно анимировать, системы анимации автоматически создаст изменяемые клоны замороженный Freezable объектов при попытке их с помощью анимации Storyboard.Note 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.

<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:

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

Так как не все средства чтения XAML распознают этот атрибут, рекомендуется использовать mc: Ignorable-атрибут для пометки Presentation:Freeze атрибут ignorable как: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:

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

Дополнительные сведения см. в разделе mc: Ignorable-атрибут страницы.For more information, see the mc:Ignorable Attribute page.

«Размораживание» Freezable"Unfreezing" a Freezable

После фиксации Freezable никогда не может быть изменен или разморозить; тем не менее, можно создать с помощью незафиксированную копию Clone или CloneCurrentValue метод.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.

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.

Clone И CloneCurrentValue методы создают детальные копии объекта freezable.The Clone and CloneCurrentValue methods produce deep copies of the freezable. Если объект freezable содержит другие зафиксированные объекты 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.

Создание собственного класса FreezableCreating 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.

  • Подробные уведомления об изменениях: В отличие от других DependencyObjects, объектах класса Freezable предоставить уведомление об изменениях, при изменении значений вложенных свойств.Detailed change notification: Unlike other DependencyObjects, Freezable objects provide change notifications when sub-property values change.

  • Удобное клонирование: Freezable класс уже реализовал несколько методов, которые обеспечивают большую глубину клонирования.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:

  • В начале любого APIAPI , считывает элементы данных не свойство зависимости, вызовите ReadPreamble метод.At the beginning of any APIAPI 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. (После вызова WritePreamble в APIAPI, не требуется дополнительный вызов к ReadPreamble также считывать элементы данных не свойство зависимости.)(Once you've called WritePreamble in an APIAPI, 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