Freezable オブジェクトの概要Freezable Objects Overview

このトピックでは、 Freezable オブジェクトを効果的に使用し、作成する方法を説明します。 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 オブジェクトは、非フリーズとフリーズの 2 つの状態を持つ特殊な型です。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.

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.

Freezable オブジェクトの使用Using 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

Freezable オブジェクトをフリーズするFreezing 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 はアニメーション化できません。Storyboardを使用してアニメーション化しようとすると、アニメーション システムはフリーズされたFreezableオブジェクトの変更可能な複製を自動的に作成します。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属性を無視できます。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.

「固定解除する」フリーズ可能オブジェクト"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.

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.

Freezable クラスの作成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.

  • 簡単に複製: Freezable クラスは既にディープ クローンを生成するいくつかのメソッドを実装します。Easy cloning: the Freezable class has already implemented several methods that produce deep clones.

AFreezableの種類は、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