#c# #wpf #xaml
#c# #wpf #xaml
Вопрос:
Я создал анимационную раскадровку в файле xaml. Эта раскадровка начинается при нажатии кнопки. Но чтобы остановить анимацию, я пытаюсь остановить раскадровку в моем пользовательском событии в code behind. Код не выдает никаких исключений, но когда мое событие было запущено, анимация все еще продолжается.
Я думаю, проблема в методе Stop. Для остановки требуется тот же объект, с которого начинается анимация. Но здесь раскадровка начинается в WPF xaml, и я останавливаю ее в коде позади.
Любое решение, как получить объект Xaml в коде позади или любое альтернативное решение для этого??
КОД XAML:
<Canvas.Triggers>
<EventTrigger RoutedEvent="Button.Click" SourceName="ScanButton">
<EventTrigger.Actions>
<BeginStoryboard >
<Storyboard Name="MovingServer" Storyboard.TargetName="ImageMove" RepeatBehavior="Forever" >
<DoubleAnimation Storyboard.TargetProperty="(Canvas.Left)" Duration="0:0:2" From="30" To="300" BeginTime="0:0:0" />
<DoubleAnimation Storyboard.TargetProperty="(Canvas.Left)" Duration="0:0:5" From="300" To="300" BeginTime="0:0:5" />
<DoubleAnimation Storyboard.TargetProperty="(Canvas.Left)" Duration="0:0:2" From="300" To="600" BeginTime="0:0:7" />
<DoubleAnimation Storyboard.TargetProperty="Opacity" Duration="0:0:2" From="1" To="0" BeginTime="0:0:7" />
</Storyboard>
</BeginStoryboard>
</EventTrigger.Actions>
</EventTrigger>
Код позади:
private void EventPublisher_OnScanningFinish(object sender, EventArgs args)
{
Dispatcher.Invoke(DispatcherPriority.Normal, (Action)delegate() { this.StopScanningAnimation(); });
}
private void StopScanningAnimation()
{
ServerView.StoryBoardServerScrolling.Stop(this); //---------- Not Working
//this.ServerView.Server1Static.Visibility = System.Windows.Visibility.Hidden;
//this.ServerView.Server2Static.Visibility = System.Windows.Visibility.Hidden;
//this.ServerView.Server3Scrolling.Visibility = System.Windows.Visibility.Hidden;
//this.ServerView.SearchingGlass.Visibility = System.Windows.Visibility.Hidden;
}
Ответ №1:
Определите раскадровку как статический ресурс,
<MyControl.Resources>
<Storyboard Key="MovingServer" Storyboard.TargetName="ImageMove" RepeatBehavior="Forever" >
<DoubleAnimation Storyboard.TargetProperty="(Canvas.Left)" Duration="0:0:2" From="30" To="300" BeginTime="0:0:0" />
<DoubleAnimation Storyboard.TargetProperty="(Canvas.Left)" Duration="0:0:5" From="300" To="300" BeginTime="0:0:5" />
<DoubleAnimation Storyboard.TargetProperty="(Canvas.Left)" Duration="0:0:2" From="300" To="600" BeginTime="0:0:7" />
<DoubleAnimation Storyboard.TargetProperty="Opacity" Duration="0:0:2" From="1" To="0" BeginTime="0:0:7" />
</Storyboard>
</MyControl.Resources>
и ссылаться на это из вашего внутреннего кода следующим образом :
StoryBoard board = (StoryBoard)this.FindResource("MovingServer");
board.stop();
запустите анимацию из события «click» кнопки (я не знаю, определено ли это вами в xaml, но вот как это было бы сделано, если бы вы это сделали)
<Button x:Name="ScanButton" onClick="Scanbutton_Click"></button>
protected void Scanbutton_Click(object Sender, EventArgs e)
{
StoryBoard board = (StoryBoard)this.FindResource("MovingServer");
board.start();
}
Комментарии:
1. Вы это тестировали?
StaticResources
? Вы имели в виду простоResources
? Что насчетx:Key
?2. Я тестирую пример кода, который работает, но мой текущий реальный код слишком длинный, поэтому я ищу альтернативы
3. @H.B. Извините, не могу протестировать этот код прямо сейчас. вы правы со StaticResources, это должно быть ‘resources’, я изменю это прямо сейчас. Ключ x:; часть ‘x:’ необязательна
4. Просто хотел указать на тот факт, что вам нужно добавить ключ вместо имени. Также: у меня была та же идея, и я попробовал ее, похоже, анимация тоже не останавливается.
5. @ Я пробовал с ресурсом Windows… Это не работает… K Обновить его
Ответ №2:
Я благодарен Тимоти за то, что он подал хорошую идею. Здесь я публикую свой рабочий код
/*create this resources as global to that perticular xaml. Need not to be put it in App.xaml
MyControl could be Window or Page or UserControl */
<MyControl.Resources>
<Storyboard x:Key="MovingServer" Storyboard.TargetName="MyImage" RepeatBehavior="Forever" >
<DoubleAnimation Storyboard.TargetProperty="(Canvas.Left)" Duration="0:0:2" From="30" To="300" BeginTime="0:0:0" />
<DoubleAnimation Storyboard.TargetProperty="(Canvas.Left)" Duration="0:0:5" From="300" To="300" BeginTime="0:0:5" />
<DoubleAnimation Storyboard.TargetProperty="(Canvas.Left)" Duration="0:0:2" From="300" To="600" BeginTime="0:0:7" />
<DoubleAnimation Storyboard.TargetProperty="Opacity" Duration="0:0:2" From="1" To="0" BeginTime="0:0:7" />
</Storyboard>
</MyControl.Resources>
/* <!-- Now use those animation resources, the place where you want. You can use it as static resource and begin stop animation from code behind OR use it as trigger event --> */
/* <!-- Static resources--> */
<Canvas>
<Image Canvas.Left="0" Canvas.Top="-2" Height="32" Name="MyImage" Width="32" Source="/CCTrayHelper;component/Images/ServerIcon.png" Visibility="Hidden"/>
<Canvas.Resources>
<BeginStoryboard x:Key="serverAnimate" Storyboard="{StaticResource MovingServer}" />
</Canvas.Resources>
</Canvas>
<Button x:Name="ScanButton" onClick="Scanbutton_Click" />
/* ****************************************************************** */
/* Code behind to start/stop animation*/
//Get the resource value first on current object, so that when you start/stop the animation, it work only on current object
Storyboard sbImageAnimate = (Storyboard)this.ServerView.FindResource("MovingServer");
//Start the animation on Button Click
protected void Scanbutton_Click(object Sender, EventArgs e)
{
this.MyImage.Visibility = System.Windows.Visibility.Visible;
sbImageAnimate.Begin();
}
//Stop animation on my own even. You can use it on any event
private void EventPublisher_OnFinish(object sender, EventArgs args)
{
Dispatcher.Invoke(DispatcherPriority.Normal, (Action)delegate() { this.StopScanningAnimation(); });
}
private void StopScanningAnimation()
{
sbImageAnimate.Stop();
this.MyImage.Visibility = System.Windows.Visibility.Hidden;
}
Ответ №3:
Я решаю проблему с помощью Stop()
метода класса Storyboard следующим образом
myStoryBoard.Stop(this.LayoutRoot);
с помощью этого решения вам не нужно объявлять раскадровку на ресурсе.
Комментарии:
1. Чтобы это было возможно, при запуске анимации вы должны установить второму параметру значение true: Begin(DependencyObject…, разрешает модификацию).