Freezable Nesnelerine Genel Bakış

Bu konuda, uygulama performansını iyileştirmeye yardımcı olabilecek özel özellikler sağlayan nesnelerin etkili bir şekilde nasıl kullanılacağı ve oluşturulacağı Freezable açıklanmaktadır. Dondurulabilir nesnelere örnek olarak fırçalar, kalemler, dönüşümler, geometriler ve animasyonlar verilebilir.

Freezable Nedir?

A Freezable , iki durumu olan özel bir nesne türüdür: dondurulmamış ve dondurulmuş. Çözülmediğinde, başka bir nesne gibi davranan bir Freezable görünür. Dondurulduğunda, Freezable artık değiştirilemez.

A Freezable , nesnedeki değişiklikleri gözlemcilere bildirmek için bir Changed olay sağlar. Freezable Artık değişiklik bildirimlerine kaynak harcaması gerekmediğinden dondurulması performansını artırabilir. Dondurulanlar Freezable iş parçacıkları arasında paylaşılabilirken, dondurulmamış Freezable bir öğe paylaşamaz.

Sınıfında birçok uygulama olsa Freezable da, Windows Presentation Foundation'daki (WPF) nesnelerin çoğu Freezable grafik alt sistemiyle ilişkilidir.

sınıfı, Freezable belirli grafik sistemi nesnelerinin kullanımını kolaylaştırır ve uygulama performansını geliştirmeye yardımcı olabilir. öğesinden Freezable devralan türlere örnek olarak , Transformve Geometry sınıfları verilebilirBrush. Yönetilmeyen kaynaklar içerdiğinden, sistemin bu nesneleri değişiklikler için izlemesi ve özgün nesnede bir değişiklik olduğunda ilgili yönetilmeyen kaynaklarını güncelleştirmesi gerekir. Bir grafik sistemi nesnesini gerçekten değiştirmeseniz bile, değiştirmeniz durumunda sistem yine de nesnenin izlenmesi için kaynaklarının bir kısmını harcamalıdır.

Örneğin, bir SolidColorBrush fırça oluşturduğunuzu ve düğmenin arka planını boyamak için kullandığınızı varsayalım.

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

Düğme işlendiğinde WPF grafik alt sistemi, bir düğmenin görünümünü oluşturmak üzere bir grup pikseli boyamak için sağladığınız bilgileri kullanır. Düğmenin nasıl boyanması gerektiğini açıklamak için düz bir renk fırçası kullansanız da, düz renk fırçanız aslında resmi yapmaz. Grafik sistemi, düğme ve fırça için hızlı, düşük düzeyli nesneler oluşturur ve aslında ekranda görünen nesnelerdir.

Fırçayı değiştirirseniz, bu alt düzey nesnelerin yeniden üretilmesi gerekir. Freezable sınıfı, fırçaya karşılık gelen oluşturulan, düşük düzeyli nesneleri bulma ve değiştiğinde bunları güncelleştirme olanağı veren sınıftır. Bu özellik etkinleştirildiğinde fırçanın "dondurılmamış" olduğu söylenir.

Freezable yöntemi Freeze , bu kendi kendini güncelleştirme özelliğini devre dışı bırakmanızı sağlar. Fırçanın "donduruldu" veya değiştirilemez hale gelmesini sağlamak için bu yöntemi kullanabilirsiniz.

Dekont

Her Freezable nesnesi dondurulamaz. oluşturmasını InvalidOperationExceptionönlemek için Freezable nesnesinin CanFreeze özelliğini dondurmaya çalışmadan önce dondurulup dondurulamayacağını belirlemek için değerini denetleyin.

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

Artık dondurulabilir bir dondurmayı değiştirmeniz gerekmeyen dondurma, performans avantajları sağlar. Bu örnekte fırçayı donduracak olursanız grafik sisteminin artık değişiklikleri izlemesi gerekmez. Grafik sistemi, fırçanın değişmeyeceğini bildiği için başka iyileştirmeler de yapabilir.

Dekont

Kolaylık olması için, siz açıkça dondurmadığınız sürece dondurulabilir nesneler dondurulmamış olarak kalır.

Freezables'ı kullanma

Dondurulmamış bir dondurulabilir kullanmak, başka bir nesne türü kullanmak gibidir. Aşağıdaki örnekte, bir SolidColorBrush düğmenin arka planını boyamak için kullanıldığında rengi sarıdan kırmızıya değiştirilir. Ekran bir sonraki yenilendiğinde düğmeyi otomatik olarak sarıdan kırmızıya değiştirmek için grafik sistemi arka planda çalışır.

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 Dondurma

Değiştirilemez hale Freezable getirmek için yöntemini çağırırsınız Freeze . Dondurulabilir nesneler içeren bir nesneyi dondurduğunuz zaman, bu nesneler de dondurulur. Örneğin, bir PathGeometryöğesini dondurduysanız, içerdiği şekiller ve segmentler de dondurulur.

Aşağıdakilerden biri doğruysa Freezable dondurulamaz :

Bu koşullar yanlışsa ve üzerinde değişiklik Freezableyapmayı düşünmüyorsanız, daha önce açıklanan performans avantajlarını elde etmek için bu koşulları dondurmanız gerekir.

Bir freezable Freeze yöntemini çağırdığınızda, artık değiştirilemez. Donmuş bir nesneyi değiştirmeye çalışmak, bir'in InvalidOperationException atılması neden olur. Aşağıdaki kod, dondurulduktan sonra fırçayı değiştirmeyi denediğimiz için bir özel durum oluşturur.


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

Bu özel durumun oluşmasını önlemek için yöntemini kullanarak bir Freezable öğesinin IsFrozen dondurulup dondurulmadığını belirleyebilirsiniz.


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


Yukarıdaki kod örneğinde, yöntemi kullanılarak Clone dondurulmuş bir nesneden değiştirilebilir bir kopya yapılmıştır. Sonraki bölümde kopyalama işlemi daha ayrıntılı olarak ele alınmaktadır.

Dekont

Donmuş dondurma animasyonu yapılamadığından, animasyon sistemi ile animasyon eklemeye çalıştığınızda donmuş Freezable nesnelerin değiştirilebilir kopyalarını Storyboardotomatik olarak oluşturur. Kopyalamanın neden olduğu performans ek yükünü ortadan kaldırmak için, animasyon eklemek istiyorsanız nesneyi dondurmamış olarak bırakın. Görsel taslaklarla animasyon oluşturma hakkında daha fazla bilgi için bkz . Görsel Taslaklara Genel Bakış.

İşaretlemeden Donma

İşaretlemeyi bildirilen bir Freezable nesneyi dondurmak için özniteliğini PresentationOptions:Freeze kullanırsınız. Aşağıdaki örnekte, bir SolidColorBrush sayfa kaynağı olarak bildirilir ve dondurulur. Ardından bir düğmenin arka planını ayarlamak için kullanılır.

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

özniteliğini Freeze kullanmak için sunu seçenekleri ad alanına eşlemelisiniz: http://schemas.microsoft.com/winfx/2006/xaml/presentation/options. PresentationOptions bu ad alanını eşlemek için önerilen ön ektir:

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

Tüm XAML okuyucuları bu özniteliği tanımadığından, özniteliği yoksayılabilir olarak işaretlemek için mc:Ignorable ÖzniteliğiniPresentationOptions:Freeze kullanmanız önerilir:

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

Daha fazla bilgi için mc:Ignorable Özniteliği sayfasına bakın.

Bir Freezable 'Unfreezing'

Dondurulduktan sonra, bir Freezable asla değiştirilemez veya çözülemez; ancak veya CloneCurrentValue yöntemini kullanarak Clone dondurulmamış bir kopya oluşturabilirsiniz.

Aşağıdaki örnekte düğmenin arka planı bir fırçayla ayarlanır ve bu fırça dondurulur. Yöntemi kullanılarak Clone fırçadan çözülmemiş bir kopya oluşturulur. Kopya değiştirilir ve düğmenin arka planını sarıdan kırmızıya değiştirmek için kullanılır.

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

Dekont

Hangi kopyalama yöntemini kullandığınızdan bağımsız olarak, animasyonlar hiçbir zaman yeni Freezableöğesine kopyalanır.

Clone ve CloneCurrentValue yöntemleri, dondurulabilir değerin derin kopyalarını oluşturur. Dondurulabilen başka dondurulabilir nesneler içeriyorsa, bunlar da kopyalanıp değiştirilebilir hale gelir. Örneğin, dondurulmuş PathGeometry bir öğeyi değiştirilebilir hale getirmek için kopyalarsanız, içerdiği şekiller ve segmentler de kopyalanır ve değiştirilebilir hale gelir.

Kendi Freezable Sınıfınızı Oluşturma

öğesinden Freezable türetilen bir sınıf aşağıdaki özellikleri kazanır.

  • Özel durumlar: salt okunur (dondurulmuş) ve yazılabilir durum.

  • İş parçacığı güvenliği: Dondurulmuş Freezable bir iş parçacıkları arasında paylaşılabilir.

  • Ayrıntılı değişiklik bildirimi: Diğer DependencyObjectnesnelerin aksine Freezable nesneleri, alt özellik değerleri değiştiğinde değişiklik bildirimleri sağlar.

  • Kolay kopyalama: Freezable sınıfı zaten derin klonlar üreten çeşitli yöntemler uygulamıştır.

A Freezable , türündedir DependencyObjectve bu nedenle bağımlılık özellik sistemini kullanır. Sınıf özelliklerinizin bağımlılık özellikleri olması gerekmez, ancak bağımlılık özelliklerini kullanmak yazmanız gereken kod miktarını azaltır, çünkü Freezable sınıf bağımlılık özellikleri göz önünde bulundurularak tasarlanmıştır. Bağımlılık özellik sistemi hakkında daha fazla bilgi için bkz. Bağımlılık Özelliklerine Genel Bakış.

Her Freezable alt sınıf yöntemini geçersiz kılmalıdır CreateInstanceCore . Sınıfınız tüm verileri için bağımlılık özelliklerini kullanıyorsa işiniz tamamlanmıştır.

Sınıfınız bağımlılık dışı özellik veri üyeleri içeriyorsa, aşağıdaki yöntemleri de geçersiz kılmanız gerekir:

Bağımlılık özellikleri olmayan veri üyelerine erişmek ve bu üyelere yazmak için aşağıdaki kurallara da dikkat etmeniz gerekir:

  • Bağımlılık dışı özellik veri üyelerini okuyan herhangi bir API'nin başında yöntemini çağırın ReadPreamble .

  • Bağımlılık dışı özellik veri üyeleri yazan herhangi bir API'nin başında yöntemini çağırın WritePreamble . (API'de arama WritePreamble yaptıktan sonra bağımlılık dışı özellik veri üyelerini de okursanız öğesine ek çağrı ReadPreamble yapmanız gerekmez.)

  • Bağımlılık dışı özellik veri üyelerine WritePostscript yazan yöntemlerden çıkmadan önce yöntemini çağırın.

Sınıfınız nesne olan bağımlılık-özellik olmayan veri üyeleri DependencyObject içeriyorsa, üyeyi OnFreezablePropertyChangednullolarak ayarlamış olsanız bile değerlerinden birini her değiştirdiğinizde yöntemini de çağırmalısınız.

Dekont

Geçersiz kıldığınız her Freezable yöntemi temel uygulamaya yönelik bir çağrıyla başlatmanız çok önemlidir.

Özel Freezable sınıf örneği için bkz . Özel Animasyon Örneği.

Ayrıca bkz.