#c# #wpf #xaml #animation
#c# #wpf #xaml #Анимация
Вопрос:
У меня есть приложение WPF, которое загружается Pages
в шаблонном NavigationWindow
виде . Я хотел бы реализовать переход слайдов при загрузке новой страницы, и поскольку размер окна можно изменять, целевые значения для преобразования должны определяться программно, насколько мне известно.
Я попробовал следующее в NavigationWindow
коде, но это не имеет никакого эффекта при срабатывании. PageContentContainerTransform
Он также находится в правильном месте, как определено в отладчике.
public void DoTransition()
{
double targetX = this.ActualWidth;
this.TransitionStoryboard.Stop();
this.TransitionStoryboard.Children.Clear();
IEasingFunction easing = new QuadraticEase() { EasingMode = EasingMode.EaseOut };
DoubleAnimation translateXAnim = new DoubleAnimation() {
To = targetX,
Duration = TimeSpan.FromMilliseconds(250),
EasingFunction = easing,
};
DependencyObject d = this.Template.FindName("pageContentContainerTransform", this) as DependencyObject;
Storyboard.SetTarget(translateXAnim, d);
Storyboard.SetTargetProperty(translateXAnim, new PropertyPath(TranslateTransform.XProperty));
this.TransitionStoryboard.Children.Add(translateXAnim);
this.TransitionStoryboard.Begin();
}
Это файл Template
ControlTemplate
, содержащий следующий бит XAML,
...
<ContentPresenter
Grid.Row="1"
x:Name="pageContentContainer"
MaxHeight="{StaticResource ContentWindowMaxHeight}"
MaxWidth="{StaticResource ContentWindowMaxWidth}"
RenderTransformOrigin="0.5,0.5">
<ContentPresenter.RenderTransform>
<TranslateTransform x:Name="pageContentContainerTransform" X="0" Y="0" />
</ContentPresenter.RenderTransform>
</ContentPresenter>
...
Почему нет никакого эффекта?
Обновить
Анимация работает, если вы анимируете элемент напрямую, не заключая его в Storyboard
объект. Например.
public void DoTransition()
{
double targetX = this.ActualWidth;
this.TransitionStoryboard.Stop();
this.TransitionStoryboard.Children.Clear();
IEasingFunction easing = new QuadraticEase() { EasingMode = EasingMode.EaseOut };
DoubleAnimation translateXAnim = new DoubleAnimation() {
To = targetX,
Duration = TimeSpan.FromMilliseconds(250),
EasingFunction = easing,
};
TranslateTransform t = this.Template.FindName("pageContentContainerTransform", this) as TranslateTransform;
t.BeginAnimation(TranslateTransform.XProperty, translateXAnim);
}
Однако, по-видимому, вы упускаете некоторые полезные элементы управления для анимации, которые предоставляет объект раскадровки, например, управление анимацией (остановка, запуск и т.д.). По-видимому, существуют возможные аргументы для .Begin()
объекта раскадровки, которые уместны для использования в шаблоне, однако вызов with .Begin(this, this.Template)
также ничего не делает.
Комментарии:
1. возможно, вы можете создать свойство зависимости, привязать к нему свое преобразование и анимировать свойство для упрощения манипуляций. доступ к объектам внутри элемента управления или шаблона данных — сложная задача. вы также можете попытаться найти любую ошибку данных в окне вывода во время запуска приложения.
2. По какой-то причине я думаю, что это было бы проще, если бы вы использовали визуальный диспетчер состояний, пример, хотя и не совсем то, что вы ищете silverlightshow.net/items /…
3. Преобразования слайдов — непростая задача для разработки. Вам гораздо лучше использовать уже существующую библиотеку, такую как Transitionals .
Ответ №1:
В конце концов, сочетание факторов заставило его работать. Во-первых, используйте Storyboard.SetTargetName
вместо Storyboard.SetTarget
. Во-вторых, передайте Begin()
методу контекст шаблона. Например.
public void DoTransition()
{
double targetX = this.ActualWidth;
this.TransitionStoryboard.Stop();
this.TransitionStoryboard.Children.Clear();
IEasingFunction easing = new QuadraticEase() { EasingMode = EasingMode.EaseOut };
DoubleAnimation translateXAnim = new DoubleAnimation() {
To = targetX,
Duration = TimeSpan.FromMilliseconds(250),
EasingFunction = easing,
};
// 1. Refer to the element by Name
Storyboard.SetTargetName(translateXAnim, "pageContentContainerTransform");
Storyboard.SetTargetProperty(translateXAnim, new PropertyPath(TranslateTransform.XProperty));
this.TransitionStoryboard.Children.Add(translateXAnim);
// 2. Pass in the template context here
this.TransitionStoryboard.Begin(this, this.Template);
}
Я не понимаю, почему SetTargetProperty
это не работает, если учесть, что FindName
правильно идентифицирован элемент в шаблоне, но в любом случае вышеуказанные методы работают.