Animasyon İpuçları ve Püf Noktaları
WPF'de animasyonlarla çalışırken, animasyonlarınızın daha iyi performans göstermesini ve sizi sinirlendirmesini sağlayabilen bir dizi ipucu ve püf noktası vardır.
Genel Sorunlar
Kaydırma Çubuğunun veya Kaydırıcının KonumunuN Animasyonunu Oluşturmak Onu Donduruyor
(varsayılan değer) içeren bir animasyon FillBehaviorHoldEnd kullanarak kaydırma çubuğunun veya kaydırıcının konumuna animasyon eklerseniz, kullanıcı artık kaydırma çubuğunu veya kaydırıcıyı taşıyamaz. Bunun nedeni, animasyon sona ermiş olsa da hedef özelliğin temel değerini geçersiz kılmaya devam ediyor olmasıdır. Animasyonun özelliğin geçerli değerini geçersiz kılmasını durdurmak için kaldırın veya değerini FillBehaviorStopverin. Daha fazla bilgi ve örnek için bkz . Görsel Taslakla Animasyonu Yaptıktan Sonra Özellik Ayarlama.
AnimasyonUn Çıkışını Animasyona Animasyon Eklemenin Hiçbir Etkisi Yok
Başka bir animasyonun çıkışı olan bir nesneye animasyon ekleyemezsiniz. Örneğin, 'den RadialGradientBrushSolidColorBrushöğesine animasyon eklemek için RectangleFill bir kullanırsanızObjectAnimationUsingKeyFrames, veya SolidColorBrush'nin hiçbir özelliğine RadialGradientBrush animasyon ekleyemezsiniz.
Animasyon Uygulandıktan Sonra Özelliğin Değeri Değiştirilemez
Bazı durumlarda, animasyon sona erdikten sonra bile bir özelliğin değerini değiştiremeyebilirsiniz. Bunun nedeni, animasyon sona ermiş olsa da özelliğin temel değerini geçersiz kılmaya devam ediyor olmasıdır. Animasyonun özelliğin geçerli değerini geçersiz kılmasını durdurmak için kaldırın veya değerini FillBehaviorStopverin. Daha fazla bilgi ve örnek için bkz . Görsel Taslakla Animasyonu Yaptıktan Sonra Özellik Ayarlama.
Zaman Çizelgesini Değiştirmenin Hiçbir Etkisi Yoktur
Çoğu Timeline özellik animatable olsa da ve veriye bağlı olsa da, etkin Timeline bir özelliğin özellik değerlerini değiştirmenin hiçbir etkisi yok gibi görünüyor. Bunun nedeni, bir Timeline başlatıldığında zamanlama sisteminin öğesinin bir kopyasını oluşturması ve bunu kullanarak bir Clock nesne oluşturmasıdırTimeline. Özgün kopyayı değiştirmenin sistemin kopyası üzerinde hiçbir etkisi yoktur.
Bir Timeline öğesinin değişiklikleri yansıtması için saatinin yeniden oluşturulması ve daha önce oluşturulan saati değiştirmek için kullanılması gerekir. Saatler sizin için otomatik olarak yeniden oluşturulmuyor. Zaman çizelgesi değişikliklerini uygulamanın birkaç yolu şunlardır:
Zaman çizelgesi ise veya bir Storyboardöğesine aitse, veya yöntemini kullanarak BeginStoryboard görsel taslaklarını yeniden ekleyerek değişiklikleri yansıtmasını Begin sağlayabilirsiniz. Bu, animasyonu yeniden başlatmanın yan etkisine sahiptir. Kodda, görsel şeridi önceki konumuna geri döndürmek için yöntemini kullanabilirsiniz Seek .
Yöntemini kullanarak BeginAnimation bir özelliğe doğrudan bir animasyon uyguladıysanız, yöntemini yeniden çağırın BeginAnimation ve değiştirilen animasyonu geçirin.
Doğrudan saat düzeyinde çalışıyorsanız, yeni bir saat kümesi oluşturup uygulayın ve bunları önceki oluşturulan saat kümesini değiştirmek için kullanın.
Zaman çizelgeleri ve saatler hakkında daha fazla bilgi için bkz . Animasyon ve Zamanlama Sistemine Genel Bakış.
FillBehavior.Stop Beklendiği Gibi Çalışmıyor
özelliği ayarının FillBehavior hiçbir etkisi yokmuş gibi göründüğü zamanlar vardır; örneğin, bir animasyonun ayarı SnapshotAndReplaceolduğu için başka bir HandoffBehavior animasyona "ilerlerStop".
Aşağıdaki örnek bir Canvas, a Rectangle ve oluşturur TranslateTransform. , TranslateTransform öğesinin çevresinde Canvashareket Rectangle ettirmek için animasyonlu olacaktır.
<Canvas Width="600" Height="200">
<Rectangle
Canvas.Top="50" Canvas.Left="0"
Width="50" Height="50" Fill="Red">
<Rectangle.RenderTransform>
<TranslateTransform
x:Name="MyTranslateTransform"
X="0" Y="0" />
</Rectangle.RenderTransform>
</Rectangle>
</Canvas>
Bu bölümdeki örnekler, özelliğin beklediğiniz gibi davranmadığı FillBehavior çeşitli durumları göstermek için önceki nesneleri kullanır.
FillBehavior="Stop" and HandoffBehavior with Multiple Animations
Bazen animasyon, ikinci bir animasyonla değiştirildiğinde özelliğini yoksayar FillBehavior gibi görünür. İki nesne oluşturan Storyboard ve bunları önceki örnekte gösterilene animasyon TranslateTransform eklemek için kullanan aşağıdaki örneği alın.
İlk Storyboard, , B1
0 ile 350'nin TranslateTransform özelliğine animasyon X ekler ve dikdörtgeni 350 piksel sağa taşır. Animasyon süresinin sonuna ulaştığında ve yürütmeyi durdurduğunda, X özellik özgün değeri olan 0'a geri döner. Sonuç olarak dikdörtgen 350 piksel sağa taşınır ve özgün konumuna geri döner.
<Button Content="Start Storyboard B1">
<Button.Triggers>
<EventTrigger RoutedEvent="Button.Click">
<BeginStoryboard>
<Storyboard x:Name="B1">
<DoubleAnimation
Storyboard.TargetName="MyTranslateTransform"
Storyboard.TargetProperty="X"
From="0" To="350" Duration="0:0:5"
FillBehavior="Stop"
/>
</Storyboard>
</BeginStoryboard>
</EventTrigger>
</Button.Triggers>
</Button>
İkinci Storyboard, B2
, aynı XTranslateTransformözelliğinin de animasyonunu oluşturur. Bu animasyonun ToStoryboard yalnızca özelliği ayarlandığından animasyon, animasyonun başlangıç değeri olarak animasyon verdiği özelliğin geçerli değerini kullanır.
<!-- Animates the same object and property as the preceding
Storyboard. -->
<Button Content="Start Storyboard B2">
<Button.Triggers>
<EventTrigger RoutedEvent="Button.Click">
<BeginStoryboard>
<Storyboard x:Name="B2">
<DoubleAnimation
Storyboard.TargetName="MyTranslateTransform"
Storyboard.TargetProperty="X"
To="500" Duration="0:0:5"
FillBehavior="Stop" />
</Storyboard>
</BeginStoryboard>
</EventTrigger>
</Button.Triggers>
</Button>
İlki Storyboard yürütülüyorken ikinci düğmeye tıklarsanız aşağıdaki davranışı bekleyebilirsiniz:
İlk görsel taslak sona erer ve dikdörtgeni özgün konumuna geri gönderir, çünkü animasyonun bir FillBehavior ' i Stopvardır.
İkinci görsel taslak geçerli olur ve şu anda 0 olan geçerli konumdan 500'e kadar animasyon ekler.
Ama olan bu değil. Bunun yerine dikdörtgen geri atlamaz; sağa doğru hareket etmeye devam eder. Bunun nedeni, ikinci animasyonun başlangıç değeri olarak ilk animasyonun geçerli değerini kullanması ve bu değerden 500'e animasyon eklemesidir. kullanıldığından ikinci animasyon birinci SnapshotAndReplaceHandoffBehavior animasyonun yerini alırsa, FillBehavior ilk animasyonun önemi yoktur.
FillBehavior ve Tamamlanan Olay
Sonraki örneklerde, öğesinin StopFillBehavior hiçbir etkisi olmadığı başka bir senaryo gösterilmektedir. Yine örnek, 0 ile 350'nin TranslateTransform özelliğine animasyon X eklemek için görsel taslak kullanır. Ancak, bu kez örnek olay için Completed kaydolan.
<Button Content="Start Storyboard C">
<Button.Triggers>
<EventTrigger RoutedEvent="Button.Click">
<BeginStoryboard>
<Storyboard Completed="StoryboardC_Completed">
<DoubleAnimation
Storyboard.TargetName="MyTranslateTransform"
Storyboard.TargetProperty="X"
From="0" To="350" Duration="0:0:5"
FillBehavior="Stop" />
</Storyboard>
</BeginStoryboard>
</EventTrigger>
</Button.Triggers>
</Button>
Olay işleyicisi Completed , geçerli değerinden 500'e kadar aynı özelliğe animasyon uygulayan başka bir Storyboard tane başlatır.
private void StoryboardC_Completed(object sender, EventArgs e)
{
Storyboard translationAnimationStoryboard =
(Storyboard)this.Resources["TranslationAnimationStoryboardResource"];
translationAnimationStoryboard.Begin(this);
}
Private Sub StoryboardC_Completed(ByVal sender As Object, ByVal e As EventArgs)
Dim translationAnimationStoryboard As Storyboard = CType(Me.Resources("TranslationAnimationStoryboardResource"), Storyboard)
translationAnimationStoryboard.Begin(Me)
End Sub
Aşağıda ikinciyi kaynak olarak tanımlayan Storyboard işaretleme yer alır.
<Page.Resources>
<Storyboard x:Key="TranslationAnimationStoryboardResource">
<DoubleAnimation
Storyboard.TargetName="MyTranslateTransform"
Storyboard.TargetProperty="X"
To="500" Duration="0:0:5" />
</Storyboard>
</Page.Resources>
komutunu çalıştırdığınızda özelliğinin TranslateTransform 0 ile 350 arasında animasyon eklemesini, tamamlandıktan sonra 0'a geri dönmesini Stop(FillBehaviorayarı olduğundan) ve ardından 0 ile 500 arasında animasyon eklemeyi bekleyebilirsinizX.Storyboard Bunun yerine, TranslateTransform 0 ile 350 arasında ve sonra 500'e animasyon eklenir.
Bunun nedeni WPF'nin olayları tetiklediği sıradır ve özellik değerleri önbelleğe alınır ve özellik geçersiz kılınmadığı sürece yeniden hesaplanmaz. Olay Completed , kök zaman çizelgesi (ilk Storyboard) tarafından tetiklendiğinden önce işlenir. Şu anda özellik, X henüz geçersiz kılınmadığı için animasyonlu değerini döndürür. İkincisi Storyboard , başlangıç değeri olarak önbelleğe alınan değeri kullanır ve animasyon eklemeye başlar.
Performans
Animasyonlar Sayfadan Uzaklaştıktan Sonra Çalışmaya Devam Ediyor
Çalışan animasyonlar içeren bir Page öğeden uzaklaştığınızda, bu animasyonlar çöp toplanana Page kadar yürütülmeye devam eder. Kullanmakta olduğunuz gezinti sistemine bağlı olarak, gezindiğiniz bir sayfa süresiz bir süre boyunca bellekte kalabilir ve bu süre boyunca kaynakları animasyonlarıyla birlikte tüketebilir. Bu durum, bir sayfada sürekli çalışan ("ortam") animasyonlar bulunduğunda dikkat çekicidir.
Bu nedenle, bir sayfadan Unloaded çıktığınızda animasyonları kaldırmak için olayı kullanmak iyi bir fikirdir.
Animasyonu kaldırmanın farklı yolları vardır. Aşağıdaki teknikler, bir Storyboardöğesine ait animasyonları kaldırmak için kullanılabilir.
Olay tetikleyicisiyle başladığınız bir Storyboard öğeyi kaldırmak için bkz . Nasıl yapılır: Görsel Taslak Kaldırma.
bir öğesini kaldırmak Storyboardiçin kod kullanmak için yöntemine Remove bakın.
Animasyonun nasıl başlatıldığına bakılmaksızın sonraki teknik kullanılabilir.
- Belirli bir özellikten animasyonları kaldırmak için yöntemini kullanın BeginAnimation(DependencyProperty, AnimationTimeline) . Animasyonlu özelliğini ilk parametre olarak,
null
ikinci parametre olarak belirtin. Bu, özelliğinden tüm animasyon saatlerini kaldırır.
Özelliklere animasyon eklemenin farklı yolları hakkında daha fazla bilgi için bkz . Özellik Animasyon Tekniklerine Genel Bakış.
Compose HandoffBehavior'ı Kullanmak Sistem Kaynaklarını Tüketir
kullanarakHandoffBehaviorCompose bir Storyboardözelliğine , AnimationTimelineveya AnimationClock uyguladığınızda, daha önce bu özellikle ilişkilendirilmiş tüm Clock nesneler sistem kaynaklarını kullanmaya devam eder; zamanlama sistemi bu saatleri otomatik olarak kaldırmaz.
kullanarak Composeçok sayıda saat uyguladığınızda performans sorunlarını önlemek için, oluşturma saatlerini tamamlandıktan sonra animasyonlu özellikten kaldırmanız gerekir. Bir saati kaldırmanın çeşitli yolları vardır.
Bir özellikten tüm saatleri kaldırmak için animasyonlu nesnenin veya BeginAnimation(DependencyProperty, AnimationTimeline) yöntemini kullanınApplyAnimationClock(DependencyProperty, AnimationClock). Animasyonlu özelliğini ilk parametre olarak,
null
ikinci parametre olarak belirtin. Bu, özelliğinden tüm animasyon saatlerini kaldırır.Belirli AnimationClock bir saati saat listesinden kaldırmak için özelliğini AnimationClock kullanarak Controller bir ClockControlleralın ve yöntemini çağırın RemoveClockController. Bu genellikle bir saat için olay işleyicisinde Completed yapılır. Yalnızca kök saatlerin bir ClockControllertarafından denetlenebileceğini unutmayın; Controller alt saatin özelliği döndürür
null
. Ayrıca, Completed saatin geçerlilik süresi sonsuza kadar ise olayın çağrılmadığını da unutmayın. Bu durumda, kullanıcının ne zaman çağrılacağını Removebelirlemesi gerekir.
Bu öncelikle yaşam süresi uzun olan nesnelerdeki animasyonlar için bir sorundur. Bir nesne çöp toplandığında, saatleri de kesilir ve çöp toplanır.
Saat nesneleri hakkında daha fazla bilgi için bkz . Animasyon ve Zamanlama Sistemine Genel Bakış.
Ayrıca bkz.
.NET Desktop feedback