Aracılığıyla paylaş


Donabilir Nesnelere Genel Bakış

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

Freezable Nedir?

Freezable, iki durumu olan özel bir nesne türüdür: dondurulmamış ve dondurulmuş. Çözüldüğünde, bir Freezable diğer herhangi bir nesne gibi davranır gibi görünür. Dondurulduğunda, Freezable artık değiştirilemez.

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

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

Freezable sınıfı, belirli grafik sistemi nesnelerinin kullanımını kolaylaştırır ve uygulama performansını geliştirmeye yardımcı olabilir. Freezable devralan türlere örnek olarak Brush, Transformve Geometry sınıfları verilebilir. 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çası oluşturduğunuzu ve bunu bir 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ştirecek olursanız, bu alt düzey nesnelerin yeniden üretilmesi gerekecektir. Freezable sınıfı, fırçanın, karşılık gelen düşük seviye oluşturulmuş nesneleri bulma ve değiştiğinde onları güncelleme yeteneğini kazanmasını sağlayan sınıftır. Bu özellik etkinleştirildiğinde fırçanın "dondurılmamış" olduğu söylenir.

Freezable'ın Freeze yöntemi, bu kendi kendine 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.

Not

Her bir Freezable nesnesi dondurulamaz. InvalidOperationExceptionoluşturmamak için Dondurulabilir nesnenin CanFreeze özelliğinin değerini denetleyin ve dondurmayı denemeden önce dondurulabilirliğini belirleyin.

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 nesneyi değiştirmeniz gerekmiyorsa, onu dondurmak 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.

Not

Rahatlık sağlamak amacıyla, dondurulabilir nesneler açıkça dondurmadıkça dondurulmamış olarak kalır.

Freezables'ı kullanma

Dondurulmamış bir donabilir kullanmak, herhangi bir nesne türü kullanmak gibidir. Aşağıdaki örnekte, bir düğmenin arka planını boyamak için kullanılan SolidColorBrush 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

Donması Mümkün Olan Bir Şeyi Dondurma

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

Aşağıdakilerden biri doğruysa, Freezable dondurulamaz.

  • Animasyonlu veya veriye bağlı özelliklere sahiptir.

  • Dinamik bir kaynak tarafından ayarlanan özelliklere sahiptir. (Dinamik kaynaklar hakkında daha fazla bilgi için bkz. XAML Kaynakları.)

  • Dondurulamaz Freezable alt nesneleri içerir.

Bu koşullar yanlışsa ve Freezabledeğiştirmek istemiyorsanız, daha önce açıklanan performans avantajlarını elde etmek için bunu dondurmanız gerekir.

Freezable'ın Freeze yöntemini çağırdığınızda artık değiştirilemez. Donmuş bir nesneyi değiştirmeye çalışmak bir InvalidOperationException hatası fırlatılmasına neden olur. Aşağıdaki kod, fırça dondurulmuşken onu değiştirmeyi denediğimiz için bir hata 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 istisnanın atılmasını engellemek için Freezable'in donmuş olup olmadığını belirlemek amacıyla IsFrozen yöntemini kullanabilirsiniz.


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, Clone yöntemi kullanılarak 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.

Not

Donmuş dondurulabilir bir nesne animasyon yapılamadığından, animasyon sistemi donmuş Freezable nesneleri Storyboardile animasyon eklemeye çalıştığınızda değiştirilebilir klonlar olarak otomatik olarak oluşturur. Kopyalamanın neden olduğu performans ek yükünü ortadan kaldırmak için, animasyon yapmayı düşünüyorsanız nesneyi donmamış halde bırakın. Görsel taslaklarla animasyon oluşturma hakkında daha fazla bilgi için bkz. Görsel Taslaklarına Genel Bakış.

İşaretleme Nedeniyle Donma

İşaretleme olarak tanımladığınız bir Freezable nesnesini dondurmak için PresentationOptions:Freeze özniteliğini kullanırsınız. Verilen aşağıdaki örnekte, SolidColorBrush sayfa kaynağı olarak tanımlanır 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>

Freeze özniteliğini 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, PresentationOptions:Freeze özniteliği yoksayılabilir olarak işaretlemek için mc:Ignorable Özniteliği kullanmanız önerilir:

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

Daha fazla bilgi için mc:Ignorable Attribute sayfasına bakın.

Dondurulabilir'i Çözme

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

Aşağıdaki örnekte düğmenin arka planı bir fırçayla ayarlanır ve bu fırça dondurulur. Clone yöntemi kullanılarak fırçanın dondurulmamış bir kopyası 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

Not

Klonlama yönteminiz ne olursa olsun, animasyonlar hiçbir zaman yeni Freezable'e kopyalanmaz.

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

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

Freezable'dan 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: Donmuş Freezable iş parçacıkları arasında paylaşılabilir.

  • Ayrıntılı değişiklik bildirimi: Diğer DependencyObjectaksine, 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.

Freezable bir DependencyObjecttürüdür ve 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 Bağımlılık Özelliklerine Genel Bakışbölümüne bakın.

Her Freezable alt sınıfı CreateInstanceCore yöntemini geçersiz kılmalıdır. 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 ReadPreamble yöntemini çağırın.

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

  • Bağımlılık özelliği olmayan veri üyelerine yazan yöntemlerden çıkmadan önce WritePostscript yöntemini çağırın.

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

Not

Geçersiz kıldığınız her Freezable yöntemini 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.