我正在创建一个名为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;
}
我使用以下内容在DispatchTimer中启动动画:
FadeImageStoryboard.Begin(this, this.Template, true);
在我将两个或更多ImageFader控件放在同一窗口上之前,一切正常。当我这样做时(使用DispatchTimer以不同的间隔启动动画),两个ImageFaders的故事板完成事件运行。
我相信我的控制权是将模板资源中的故事板作为静态参考。
我该如何避免这种情况?
答案 0 :(得分:2)
一个解决方案可能是从代码创建故事板,它不会太难看:)
只需更改此代码:
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;
}
每个控件都会获得它自己的故事板。我不认为将这些故事板作为模板的一部分是一个好主意,因为它们是这种控制的正确行为的一个重要部分,并且也没有太多东西可以改变它们(所以在几乎所有代码必须重复的模板。)