2011-05-26 8 views
8

.Net 4.0 kullanarak bazı WPF denetimleri yapıyorum. LoadingPane olarak adlandırılan bu denetimlerden biri, ContentControl'den türetilen özel bir denetimdir. Bu Yükleme Parçası denetiminin tek işi, Isloading özelliği true olarak ayarlandığında içerdiği içerik üzerinde yarı saydam bir katman göstermektir. Isloading değeri değiştiğinde sönümleme yapmak için bazı animasyonlar kullanıyorum. Kaplama gösterildiğinde bir animasyon, bir elips çemberini döndürür.WPF Animasyon başlar ama çok geç gösterir

Şimdiye kadar çok iyi. Her şey çok güzel çalışıyor. Ama benim sorunum: Yükleme özelliğini true olarak ayarladığımda animasyon doğrudan gösterilmiyor. Yaklaşık yarım saniye sürüyor. Bu süre içinde, fade-in animasyonu zaten çalışıyor, böylece opaklık, tek adımda 0'dan 1'e etkili bir şekilde gidiyor. Daha sonra solma

<ControlTemplate.Triggers> 
    <Trigger Property="IsLoading" 
      Value="True"> 
     <Trigger.EnterActions> 
      <RemoveStoryboard BeginStoryboardName="EndAnimateLoadingCanvas" /> 
      <BeginStoryboard Name="AnimateLoadingCanvas"> 
       <Storyboard FillBehavior="Stop"> 
        <ObjectAnimationUsingKeyFrames BeginTime="00:00:00" 
                Storyboard.TargetName="MyViewBoxje" 
                Storyboard.TargetProperty="Visibility"> 
         <DiscreteObjectKeyFrame Value="{x:Static Visibility.Visible}" /> 
        </ObjectAnimationUsingKeyFrames> 

        <DoubleAnimation BeginTime="00:00:00" 
            Duration="00:00:00.5" 
            Storyboard.TargetName="MyViewBoxje" 
            Storyboard.TargetProperty="Opacity" 
            To="1" /> 

        <DoubleAnimation BeginTime="00:00:00" 
            Duration="00:00:02" 
            Storyboard.TargetName="AnimatedRotateTransform" 
            Storyboard.TargetProperty="Angle" 
            From="360" 
            To="0" 
            RepeatBehavior="Forever" /> 

       </Storyboard> 
      </BeginStoryboard> 
     </Trigger.EnterActions> 
     <Trigger.ExitActions> 
      <RemoveStoryboard BeginStoryboardName="AnimateLoadingCanvas" /> 
      <BeginStoryboard Name="EndAnimateLoadingCanvas"> 
       <Storyboard FillBehavior="Stop"> 
        <DoubleAnimation BeginTime="00:00:00" 
            Duration="00:00:00.5" 
            Storyboard.TargetName="MyViewBoxje" 
            Storyboard.TargetProperty="Opacity" 
            To="0" /> 
        <ObjectAnimationUsingKeyFrames BeginTime="00:00:00.5" 
                Storyboard.TargetName="MyViewBoxje" 
                Storyboard.TargetProperty="Visibility"> 
         <DiscreteObjectKeyFrame Value="{x:Static Visibility.Collapsed}" /> 
        </ObjectAnimationUsingKeyFrames> 

       </Storyboard> 
      </BeginStoryboard> 
     </Trigger.ExitActions> 
    </Trigger> 
</ControlTemplate.Triggers> 

tuhaf şey, ben bir test penceresinde bu denetimi kullanın ve ben defalarca Yükleme onay kutusunu tıkladığınızda (ve animasyon tamamlanmadan önce):

İşte benim animasyon kod -in/fade-out animasyon çalışmasını beklediğim gibi çalışır.

Herkes yardımcı olabilir mi? Thanx önceden!

+0

Aynı sorunu (farklı bir koşul altında da olsa) aldım. Yüklenen bir Silverlight uygulaması, animasyonu asla * ilk * saat göstermediğinde çalıştırdığım bir animasyon. Ancak müteakip yükler işe yaradı. Uygulamayı sonlandırmak ve tekrar başlatmak aynı davranışa sahip olurdum. Hiç bir cevap bulamadı +1 =) – Smudge202

+0

Bounty ekledi, belki de bunun için bir cevap bulabiliriz. Özünde, asıl soru, yük atlama animasyonlarının nasıl atlanacağını, tercihen bir ilk zamanlayıcı olayını engelleyen bir tür geçici çözüm olmaksızın nasıl önleneceğini düşünüyorum. Smudge gibi – Smudge202

+0

+1. SL ile aynı sorunları yaşıyor. –

cevap

0

Sonunda Isak cevabı okuduktan sonra anladım. Cevabın benim durumumda yardımcı olmadığını söylediğim için üzgünüm ama doğru yöne gitmemi sağladı.

İlk soluğun çalışmasının işe yaramaması sebebi, içerdiği görüntüleme kutusunun, soluk animasyonunun gerçekleştirildiği tüm zaman içinde görünmeye ayarlı görünmesine neden olmasıdır. Bu ObjectAnimationUsingKeyFrames neden oldu:

DiscreteObjectKeyFrame Value="{x:Static Visibility.Visible}" /> 
</ObjectAnimationUsingKeyFrames> 

belirtilen hiçbir süre ve çok geç canlandırılmıştır belirtilen tek anahtar kare oldu. Ekleme

Duration="00:00:00" 

benim sorun çözüldü.

Hepinize yardımcı olduğunuz için teşekkürler!

+1

yardımcı olabilir sevindim Bu benim için değildi, bu yüzden ben cevap olarak kendi cevabını işaretlemek anlatayım rağmen, iş için görünür ve gibi hizmet verecek onun tam bir örnek için isak lütuf vereceğim Gelecekte bu aynı sorunu varsa iyi bir referans. – Smudge202

3

Kodun geri kalanını görmeden sorunun tam olarak ne olduğunu görmek zor ama tahminim, animasyonlu özelliklerin başlangıç ​​değerleriyle ilgili olması gerektiğidir.

WPF'de görünüm kutusunun içinde bir dikdörtgen bulunan özel bir denetim gerçekleştirdim ve efekti görmek için sorudan tetikleyiciler + storyboard'ları kullandım. Gerçekten, ilk denemem kaybolmadı ya da kaybolmadı.

<DoubleAnimation BeginTime="00:00:00" 
     Duration="00:00:00.5" 
     Storyboard.TargetName="MyViewBoxje" 
     Storyboard.TargetProperty="Opacity" 
     From="0" 
     To="1" /> 

Bildirimi From="0" yukarıdaki animasyon: Ben bakılmaksızın DP en orijinal değeri olan ne işe böylece animasyonlar From değerlerini belirterek oldu çözmek için yaptığı şey

. Son film şeridi aynı şekilde, 1'den 0'a gitmek için değiştirildi.

Tamlık için, optomuumu ControlTemplate içindeki viewbox öğesi tanımında 0 olarak ayarladım.


İlgili bölümlerin tam kaynak kodu İşte. Kontrol, Control'dan miras alınan standart bir WPF özel kontrolüdür. Benim ana penceresinde kullanılan {x:Type local:LoadingControl}

<ControlTemplate TargetType="{x:Type local:LoadingControl}"> 
    <ControlTemplate.Triggers> 
     <Trigger Property="IsLoading" Value="True"> 
      <Trigger.EnterActions> 
       <RemoveStoryboard BeginStoryboardName="EndAnimateLoadingCanvas" /> 
       <BeginStoryboard Name="AnimateLoadingCanvas"> 
        <Storyboard FillBehavior="Stop"> 
         <ObjectAnimationUsingKeyFrames BeginTime="00:00:00" 
            Storyboard.TargetName="MyViewBoxje" 
            Storyboard.TargetProperty="Visibility"> 
          <DiscreteObjectKeyFrame Value="{x:Static Visibility.Visible}" /> 
         </ObjectAnimationUsingKeyFrames> 

         <DoubleAnimation BeginTime="00:00:00" 
            Duration="00:00:00.5" 
            Storyboard.TargetName="MyViewBoxje" 
            Storyboard.TargetProperty="Opacity" 
            From="0" 
            To="1" /> 

         <DoubleAnimation BeginTime="00:00:00" 
             Duration="00:00:02" 
             Storyboard.TargetName="AnimatedRotateTransform" 
             Storyboard.TargetProperty="Angle" 
             From="360" 
             To="0" 
             RepeatBehavior="Forever" /> 

        </Storyboard> 
       </BeginStoryboard> 
      </Trigger.EnterActions> 
      <Trigger.ExitActions> 
       <RemoveStoryboard BeginStoryboardName="AnimateLoadingCanvas" /> 
       <BeginStoryboard Name="EndAnimateLoadingCanvas"> 
        <Storyboard FillBehavior="Stop"> 
         <DoubleAnimation BeginTime="00:00:00" 
             Duration="00:00:00.5" 
             Storyboard.TargetName="MyViewBoxje" 
             Storyboard.TargetProperty="Opacity" 
             From="1" 
             To="0" /> 
         <ObjectAnimationUsingKeyFrames BeginTime="00:00:00.5" 
            Storyboard.TargetName="MyViewBoxje" 
            Storyboard.TargetProperty="Visibility"> 
          <DiscreteObjectKeyFrame Value="{x:Static Visibility.Collapsed}" /> 
         </ObjectAnimationUsingKeyFrames> 

        </Storyboard> 
       </BeginStoryboard> 
      </Trigger.ExitActions> 
     </Trigger> 
    </ControlTemplate.Triggers> 

    <Border Background="{TemplateBinding Background}" 
      BorderBrush="{TemplateBinding BorderBrush}" 
      BorderThickness="{TemplateBinding BorderThickness}"> 
     <Viewbox x:Name="MyViewBoxje" Opacity="0"> 
      <!-- BG with 0x50 alpha so that it's translucent event at 100% visibility --> 
      <Grid Width="100" Height="100" Background="#50000000"> 
       <Rectangle Width="70" Height="20" Fill="Green" Stroke="Black" StrokeThickness="2" RenderTransformOrigin="0.5,0.5"> 
        <Rectangle.RenderTransform> 
         <RotateTransform Angle="360" x:Name="AnimatedRotateTransform" /> 
        </Rectangle.RenderTransform> 
       </Rectangle> 
      </Grid> 
     </Viewbox> 
    </Border> 
</ControlTemplate> 

için tarzında generic.xaml tanımlanmıştır -

public bool IsLoading 
{ 
    get { return (bool)GetValue(IsLoadingProperty); } 
    set { SetValue(IsLoadingProperty, value); } 
} 

// Using a DependencyProperty as the backing store for IsLoading. This enables animation, styling, binding, etc... 
public static readonly DependencyProperty IsLoadingProperty = 
     DependencyProperty.Register("IsLoading", typeof(bool), typeof(LoadingControl), new UIPropertyMetadata(false)); 

ControlTemplate: Bu IsLoading (bool) adlı tek bağımlılık özelliği varsayılan false zorundadır öyleyse:

<Grid x:Name="LayoutRoot"> 
    <!-- All other stuff here ... --> 

    <my:LoadingControl IsLoading="{Binding IsLoading}" HorizontalAlignment="Stretch" VerticalAlignment="Stretch" /> 
</Grid> 

Ve bunu test etmek için Ana pencere için DataContext olarak ayarlanmış bir IsLoading özelliğine sahip bir ViewModel.Ve ViewModel yapıcısı ben true IsLoading ayarlayın ve sonra her 5 saniyede özelliğinin değerini açıp kapatan bir zamanlayıcı başlatmak:

public MainWindowViewModel() 
{ 
    IsLoading = true; 
    DispatcherTimer t = new DispatcherTimer(); 
    t.Interval = TimeSpan.FromSeconds(5); 
    t.Tick += (s, e) => IsLoading = !IsLoading; 
    t.Start(); 
} 
+0

Bir galibiyete benziyor, ancak asıl yapılacak olan şeyleri kaydetmeye sakıncası yoksa. Başarısız olduğum günden bu yana başarısız olduğum gümüş projeyi (OP hakkında bir yoruma ref). Belki de @Elad Katz da onaylayabilir? =) – Smudge202

+0

Kod eklendi –

+0

Teşekkürler Isak, bu gelecekte kullanışlı bir referans olacak. Bana izin verdiğinde ödül vereceğim. – Smudge202