powered by simpleCommunicator - 2.0.50     © 2025 Programmizd 02
Форумы / WPF, Silverlight [игнор отключен] [закрыт для гостей] / WPF MVVM - Анимация перехода между представлениями
3 сообщений из 3, страница 1 из 1
WPF MVVM - Анимация перехода между представлениями
    #39116242
Фотография Zick
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Разрабатываю проект на WPF с использованием паттерна MVVM. Использую MVVM Light. Каким образом возможно реализовать анимацию переходов от одного представления к другому? К примеру, плавное "затухание" одного и появление другого.
...
Рейтинг: 0 / 0
WPF MVVM - Анимация перехода между представлениями
    #39116397
Roman Mejtes
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Сразу предупреждаю, этот пример я писал на коленке, в нем нужно сделать проверки на значения которые передаются в AttachedProperty, так как они могут быть пустыми и сделать соответствующую логику на этот случай
Так же важно (необходим) для Storyboard для анимации До! указать длительность этой анимации
И так же важно учесть тот факт, что свойство будет удерживаться анимацией, то есть поменять его можно будет только прекратив анимацию.
Но надеюсь данного примера будет достаточно. В примере элемент ContentControl скрывается, у него меняется свойство Content и затем появляется, код в принципе универсальный :) удачи

Тестовая модель представления:
Код: c#
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
41.
42.
43.
44.
45.
46.
47.
48.
49.
50.
51.
52.
53.
54.
55.
56.
57.
58.
59.
60.
61.
62.
63.
64.
65.
66.
67.
    public class Person
    {
        private readonly string _name;
        private readonly int _age;

        public Person(string name, int age)
        {
            _name = name;
            _age = age;
        }
        public string Name { get { return _name; } }
        public int Age { get { return _age; } }
        
    }

    public class MainModel : INotifyPropertyChanged
    {
        private List<Person> _persones;
        private int _personNumber;
        private Person _currentPerson;

        private List<Person> Persones
        {
            get
            {
                return _persones ?? (_persones = new List<Person>(GetPersones()));
            }
        }

        private IEnumerable<Person> GetPersones()
        {
            yield return new Person("Roman", 31);
            yield return new Person("Sofia", 36);
            yield return new Person("Olga", 6);
            yield return new Person("Sasha", 14);
        }

        public Person CurrentPerson
        {
            private set
            {
                if (Equals(value, _currentPerson)) return;
                _currentPerson = value;
                OnPropertyChanged();
            }
            get { return _currentPerson; }
        }

        public int PersonNumber
        {
            set
            {
                _personNumber = value;
                CurrentPerson = Persones[_personNumber];
            }
            get { return _personNumber; }
        }

        public event PropertyChangedEventHandler PropertyChanged;

        [NotifyPropertyChangedInvocator]
        protected virtual void OnPropertyChanged([CallerMemberName] string propertyName = null)
        {
            PropertyChangedEventHandler handler = PropertyChanged;
            if (handler != null) handler(this, new PropertyChangedEventArgs(propertyName));
        }
    }


Окно:
Код: xml
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
<Window x:Class="WpfApplication47.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:local="clr-namespace:WpfApplication47"
        Title="MainWindow" Height="350" Width="525"
        DataContext="{StaticResource MainModel}">
    <Window.Resources>
        <DataTemplate x:Key="{x:Type local:Person}" DataType="{x:Type local:Person}">
            <StackPanel>
                <TextBlock Text="Name:"/>
                <TextBlock Text="{Binding Name}" Foreground="DarkBlue"/>
                <TextBlock Text="Age:"/>
                <TextBlock Text="{Binding Age}" Foreground="DarkGreen"/>
            </StackPanel>
        </DataTemplate>
        <Storyboard x:Key="AfterAnimation" Duration="0:0:.5">
            <DoubleAnimation Storyboard.TargetProperty="Opacity"
                             To="0" Duration="0:0:.5"/>

        </Storyboard>
        <Storyboard x:Key="BeforAnimation" Duration="0:0:.5">
            <DoubleAnimation Storyboard.TargetProperty="Opacity"
                             To="1" Duration="0:0:.5"/>
        </Storyboard>
    </Window.Resources>
    <DockPanel >
        <Slider Minimum="0" Maximum="3" DockPanel.Dock="Top"  Margin="5"
                Value="{Binding PersonNumber}"></Slider>
        <ContentControl ContentTemplate="{StaticResource {x:Type local:Person}}"
                        HorizontalAlignment="Center" VerticalAlignment="Center"
                        local:AnimationValueChanger.AfterStoryboard="{StaticResource AfterAnimation}"
                        local:AnimationValueChanger.BeforeStoryboard="{StaticResource BeforAnimation}"
                        local:AnimationValueChanger.Value="{Binding CurrentPerson}"
                        local:AnimationValueChanger.PropertyTarget="Content" />
                          
    </DockPanel>
</Window>


local:AnimationValueChanger:
Код: xml
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
41.
42.
43.
44.
45.
46.
47.
48.
49.
50.
51.
52.
53.
54.
55.
56.
57.
58.
59.
60.
61.
62.
63.
64.
65.
66.
67.
68.
69.
70.
71.
72.
73.
74.
    public class AnimationValueChanger
    {
        public static Storyboard GetAfterStoryboard(DependencyObject obj) { return (Storyboard)obj.GetValue(AfterStoryboardProperty); } 
        public static void SetAfterStoryboard(DependencyObject obj, Storyboard value)  { obj.SetValue(AfterStoryboardProperty, value); }
        public static readonly DependencyProperty AfterStoryboardProperty =
            DependencyProperty.RegisterAttached("AfterStoryboard", typeof(Storyboard), typeof(AnimationValueChanger), new PropertyMetadata(null));
        
        public static Storyboard GetBeforeStoryboard(DependencyObject obj)
        {
            return (Storyboard)obj.GetValue(BeforeStoryboardProperty);
        }

        public static void SetBeforeStoryboard(DependencyObject obj, Storyboard value)
        {
            obj.SetValue(BeforeStoryboardProperty, value);
        }
        public static readonly DependencyProperty BeforeStoryboardProperty =
            DependencyProperty.RegisterAttached("BeforeStoryboard", typeof(Storyboard), typeof(AnimationValueChanger), new PropertyMetadata(null));

        
        public static PropertyPath GetPropertyTarget(DependencyObject obj)
        {
            return (PropertyPath)obj.GetValue(PropertyTargetProperty);
        }

        public static void SetPropertyTarget(DependencyObject obj, PropertyPath value)
        {
            obj.SetValue(PropertyTargetProperty, value);
        }
        public static readonly DependencyProperty PropertyTargetProperty =
            DependencyProperty.RegisterAttached("PropertyTarget", typeof(PropertyPath), typeof(AnimationValueChanger), new PropertyMetadata(null));



        public static object GetValue(DependencyObject obj) { return obj.GetValue(ValueProperty); }
        public static void SetValue(DependencyObject obj, object value) { obj.SetValue(ValueProperty, value); }
        public static readonly DependencyProperty ValueProperty =
            DependencyProperty.RegisterAttached("Value", typeof(object), typeof(AnimationValueChanger), new FrameworkPropertyMetadata(null, OnContentChanged));

        private static void OnContentChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
        {
            var afterStoryboard = GetAfterStoryboard(d);
            var beforeStoryboard = GetBeforeStoryboard(d);
            var propertyPath = GetPropertyTarget(d);
            var content = e.NewValue;
            if (afterStoryboard == null)
            {
                d.SetValue(ContentPresenter.ContentProperty, content);
            }
            else
            {
                var setter = new ObjectAnimationUsingKeyFrames
                {
                    KeyFrames =
                    {
                        new DiscreteObjectKeyFrame
                        {
                            KeyTime =  afterStoryboard.Duration.TimeSpan,
                            Value = content
                        }
                    }
 
                };
                Storyboard.SetTargetProperty(setter, propertyPath);
                var totalStoryBoard = new Storyboard();
                beforeStoryboard.BeginTime = afterStoryboard.Duration.TimeSpan;

                totalStoryBoard.Children.Add(afterStoryboard);
                totalStoryBoard.Children.Add(setter);
                totalStoryBoard.Children.Add(beforeStoryboard);
                totalStoryBoard.Begin((FrameworkElement)d);
            }
        }
    }
...
Рейтинг: 0 / 0
WPF MVVM - Анимация перехода между представлениями
    #39116408
Roman Mejtes
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
забыл App.xaml скинуть, но он обычный
Код: xml
1.
2.
3.
4.
5.
6.
7.
8.
9.
<Application x:Class="WpfApplication47.App"
             xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
             xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
             xmlns:local="clr-namespace:WpfApplication47"
             StartupUri="MainWindow.xaml">
    <Application.Resources>
         <local:MainModel x:Key="MainModel"/>
    </Application.Resources>
</Application>
...
Рейтинг: 0 / 0
3 сообщений из 3, страница 1 из 1
Форумы / WPF, Silverlight [игнор отключен] [закрыт для гостей] / WPF MVVM - Анимация перехода между представлениями
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]