Проблемы с обработкой завершенного события раскадровки в ресурсе шаблона элемента управления - PullRequest
3 голосов
/ 07 сентября 2011

Я создаю пользовательский элемент управления под названием 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.

Я считаю, что мой элемент управления получает раскадровку из ресурсов шаблона в качестве статической ссылки.

Как мне избежать этого?

1 Ответ

2 голосов
/ 08 сентября 2011

Одним из решений может быть создание раскадровок из кода, это не выглядит слишком уродливо:)

Просто измените свой код для этого:

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;
}

И каждый элемент управления получит собственную раскадровку. Я не думаю, что создание этих раскадровок как части шаблонов является хорошей идеей, поскольку они являются неотъемлемой частью правильного поведения этого элемента управления, а также их не так уж много, чтобы изменить их (так что почти во всех шаблоны код должен быть повторен).

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...