2011-09-07 69 views
3

我正在創建一個名爲ImageFader的自定義控件。風格模板看起來是這樣的:掛鉤問題控制模板資源中的故事板完成事件

<ControlTemplate TargetType="{x:Type controls:ImageFader}"> 
    <Grid> 
     <Image HorizontalAlignment="Stretch" VerticalAlignment="Stretch" 
       Stretch="{TemplateBinding Stretch}" 
       x:Name="PART_SourceImage" Opacity="1" /> 

     <Image HorizontalAlignment="Stretch" VerticalAlignment="Stretch" 
       Stretch="{TemplateBinding Stretch}" 
       x:Name="PART_TargetImage" Opacity="0" /> 

    </Grid> 
    <ControlTemplate.Resources> 
     <Storyboard x:Key="FadeImageStoryboard"> 
      <!-- fade in the new image --> 
      <DoubleAnimation From="0" To="1" 
           Duration="{TemplateBinding FadeTime}" 
           Storyboard.TargetName="PART_TargetImage" 
           Storyboard.TargetProperty="Opacity" /> 

      <!-- fade out the previous image --> 
      <DoubleAnimation From="1" To="0" 
           Duration="{TemplateBinding FadeTime}" 
           Storyboard.TargetName="PART_SourceImage" 
           Storyboard.TargetProperty="Opacity" /> 

     </Storyboard> 
    </ControlTemplate.Resources> 
</ControlTemplate> 

在代碼中,我有這樣的:

public override void OnApplyTemplate() 
{ 
    base.OnApplyTemplate(); 

    SourceImage = Template.FindName("PART_SourceImage", this) as Image; 
    TargetImage = Template.FindName("PART_TargetImage", this) as Image; 
    FadeImageStoryboard = Template.Resources["FadeImageStoryboard"] as Storyboard; 

    FadeImageStoryboard.Completed += new EventHandler(FadeImageStoryboard_Completed); 
} 

在完成處理我想交換的圖像和重置其不透明度:

private void FadeImageStoryboard_Completed(object sender, EventArgs e) 
{ 
    SourceImage.Source = TargetImage.Source; 
    SourceImage.Opacity = 1; 
    TargetImage.Opacity = 0; 
} 

FadeImageStoryboard.Begin(this, this.Template, true); 
01:

我用這個啓動動畫DispatchTimer內

一切正常,直到我將兩個或更多的ImageFader控件放在同一個窗口中。當我這樣做時(使用DispatchTimer以不同的時間間隔開始動畫)故事板完成的事件對於兩個ImageFaders都會運行。

我相信我的控件是從模板資源中獲取故事板作爲靜態引用。

我該如何避免這種情況?

+0

你有沒有嘗試從背後的代碼創建故事板的相同的東西?這聽起來像是控件的所有實例都使用相同的資源。 – Tejs

+0

我沒有,但我想避免,如果我可以。我喜歡XAML,並且在代碼中創建故事板看起來很醜陋。 – mbursill

回答

1

一種解決方案可以從代碼中創建的故事板,它不會變得太醜陋了:),

只要改變你的代碼爲這一個:

public override void OnApplyTemplate() 
{ 
    base.OnApplyTemplate(); 

    SourceImage = Template.FindName("PART_SourceImage", this) as Image; 
    TargetImage = Template.FindName("PART_TargetImage", this) as Image; 
    FadeImageStoryboard = GetFadeImageStoryboard(); 

    FadeImageStoryboard.Completed += new EventHandler(FadeImageStoryboard_Completed); 
} 

private Storyboard GetFadeImageStoryboard() 
{ 
    DoubleAnimation fadeNewImage = new DoubleAnimation { From = 0, To = 1, Duration = FadeTime }; 
    Storyboard.SetTarget(fadeNewImage, SourceImage); 
    Storyboard.SetTargetProperty(fadeNewImage, new PropertyPath("Opacity")); 

    DoubleAnimation fadePreviousImage = new DoubleAnimation { From = 0, To = 1, Duration = FadeTime }; 
    Storyboard.SetTarget(fadePreviousImage, TargetImage); 
    Storyboard.SetTargetProperty(fadePreviousImage, new PropertyPath("Opacity")); 

    Storyboard fadeImageStoryboard = new Storyboard(); 
    fadeImageStoryboard.Children.Add(fadeNewImage); 
    fadeImageStoryboard.Children.Add(fadePreviousImage); 

    return fadeImageStoryboard; 
} 

而且每個控制會得到它自己的故事板。我不認爲將這些故事板作爲模板的一部分是一個好主意,因爲它們是該控件正確行爲的一個重要組成部分,也沒有太多東西需要改變(所以幾乎所有代碼將不得不重複的模板)。