Модераторы: gambit, Kefir, Partizan
  

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Анимация на изменения в Binding 
:(
    Опции темы
Rohoss
Дата 9.5.2011, 10:58 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Начальник интернета
***


Профиль
Группа: Завсегдатай
Сообщений: 1308
Регистрация: 9.10.2006
Где: Matrix

Репутация: 4
Всего: 18



Допустим у меня есть Image забинден к ViewModel 
Код

<Image Source="{Binding Bitmap}" />

Как мне прикрепить анимацию к изменению данных в  Bitmap? Повесить анимацию ни на DataContextChanged ни на SourceUpdate не получается  smile 

Это сообщение отредактировал(а) Rohoss - 9.5.2011, 11:04


--------------------
Файловый менеджер Explorer.Net скачать  video
PM ICQ   Вверх
-Mikle-
Дата 9.5.2011, 13:41 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Невидимка Vingrad'а
***


Профиль
Группа: Экс. модератор
Сообщений: 1672
Регистрация: 22.6.2003
Где: Казахстан, Астана

Репутация: 13
Всего: 59



Не совсем понял, что тебе требуется. У тебя меняется битмап и что-то нужно анимировать. Можно подробнее?


--------------------
Если тебе плюют в спину, значит ты впереди...
PM   Вверх
Rohoss
Дата 9.5.2011, 13:57 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Начальник интернета
***


Профиль
Группа: Завсегдатай
Сообщений: 1308
Регистрация: 9.10.2006
Где: Matrix

Репутация: 4
Всего: 18



Цитата(-Mikle- @  9.5.2011,  13:41 Найти цитируемый пост)
Не совсем понял, что тебе требуется. У тебя меняется битмап и что-то нужно анимировать. Можно подробнее? 

Просто нужно прикрутить какую нибудь анимацию к Image, которая будет вызываться при смене Bitmap


--------------------
Файловый менеджер Explorer.Net скачать  video
PM ICQ   Вверх
Rohoss
Дата 9.5.2011, 14:25 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Начальник интернета
***


Профиль
Группа: Завсегдатай
Сообщений: 1308
Регистрация: 9.10.2006
Где: Matrix

Репутация: 4
Всего: 18



Вот например анимация
Код

        <Image Width="200" Source="/WpfApp;component/Images/0034.gif">
            <Image.Triggers>
                <EventTrigger RoutedEvent="MouseLeftButtonDown">
                    <BeginStoryboard>
                        <Storyboard>
                            <DoubleAnimation By="100" Duration="0:0:2" Storyboard.TargetProperty="Width" />
                        </Storyboard>
                    </BeginStoryboard>
                </EventTrigger>
            </Image.Triggers>
        </Image>

Тут анимация повешена на событие MouseLeftButtonDown, а мне нужно как то повесить DataContextChanged или SourceUpdate или что-то в этом роде. В общем задача вызвать анимацию при изменении данных, которые биндятся к Image 


--------------------
Файловый менеджер Explorer.Net скачать  video
PM ICQ   Вверх
-Mikle-
Дата 9.5.2011, 14:54 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Невидимка Vingrad'а
***


Профиль
Группа: Экс. модератор
Сообщений: 1672
Регистрация: 22.6.2003
Где: Казахстан, Астана

Репутация: 13
Всего: 59



Что-то сходу без кодбехинда у меня тоже ничего не получилось. Через кодбехинд скорее всего получится.


--------------------
Если тебе плюют в спину, значит ты впереди...
PM   Вверх
Rohoss
Дата 9.5.2011, 16:32 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Начальник интернета
***


Профиль
Группа: Завсегдатай
Сообщений: 1308
Регистрация: 9.10.2006
Где: Matrix

Репутация: 4
Всего: 18



Цитата(-Mikle- @  9.5.2011,  14:54 Найти цитируемый пост)
Что-то сходу без кодбехинда у меня тоже ничего не получилось. Через кодбехинд скорее всего получится. 

Через кодбехинд не сложно. Обработал событие DataContextChanged, на него повесил обработчик
Код

            if (this.DataContext is MainWindowViewModel)
            {
                var dc = this.DataContext as MainWindowViewModel;

                dc.PropertyChanged += Test;
                //this.DataContext.
            }


а уже непосредственно в Test создаём анимацию
Код

        private void Test(object o, PropertyChangedEventArgs e)
        {
            var da = new DoubleAnimation();
            da.From = 0.2;
            da.To = 1;
            da.Duration = new Duration(TimeSpan.FromSeconds(0.5));
            imgMain.BeginAnimation(Image.OpacityProperty, da);


Всё работает нормально, вот только меня смущает что в кодбехинд приходится к ViewModel обращаться  smile 
Это вообще нормальная практика?

Добавлено через 2 минуты и 57 секунд
Да и анимация в коде... Если бы была какой-то сложной то ещё понятно, а так довольно простая, такую ИМХО лучше в ХАМЛ. Только вот не знаю как потом её можно подтянуть. Разместить её можно только в стиле, а если она там, то уже привязана к какому-то обработчику...


--------------------
Файловый менеджер Explorer.Net скачать  video
PM ICQ   Вверх
-Mikle-
Дата 9.5.2011, 18:36 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Невидимка Vingrad'а
***


Профиль
Группа: Экс. модератор
Сообщений: 1672
Регистрация: 22.6.2003
Где: Казахстан, Астана

Репутация: 13
Всего: 59



Цитата(Rohoss @  9.5.2011,  19:32 Найти цитируемый пост)
вот только меня смущает что в кодбехинд приходится к ViewModel обращаться   Это вообще нормальная практика?

Да, представление имеет право знать и работать с ViewModel как ей хочется, лишь бы логику не реализовывало.

Щас накатаю то же самое, только в другом оформлении. По идее должно сгодиться.


--------------------
Если тебе плюют в спину, значит ты впереди...
PM   Вверх
-Mikle-
Дата 9.5.2011, 19:05 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Невидимка Vingrad'а
***


Профиль
Группа: Экс. модератор
Сообщений: 1672
Регистрация: 22.6.2003
Где: Казахстан, Астана

Репутация: 13
Всего: 59



Значит так, где-нить создаем класс с атачед-проперти следующего содержания:
Код

    public class ImageLoad
    {
        public static Storyboard GetChangeStoryboard(Image obj) { return (Storyboard)obj.GetValue(ChangeStoryboardProperty); }
        public static void SetChangeStoryboard(Image obj, Storyboard value) { obj.SetValue(ChangeStoryboardProperty, value); }
        public static readonly DependencyProperty ChangeStoryboardProperty =
            DependencyProperty.RegisterAttached("ChangeStoryboard", typeof(Storyboard), typeof(ImageLoad),
            new PropertyMetadata(null, ChangeStoryboardChanged));

        private static void ChangeStoryboardChanged(DependencyObject sender, DependencyPropertyChangedEventArgs e)
        {
            var prop = DependencyPropertyDescriptor.FromProperty(Image.SourceProperty, typeof(Image));
            if (prop == null) return;

            if (e.NewValue != null)
                prop.AddValueChanged(sender, image_SourceChanged);
            else
                prop.RemoveValueChanged(sender, image_SourceChanged);
        }

        private static void image_SourceChanged(object sender, EventArgs e)
        {
            Image image = (Image)sender;
            Storyboard sb = GetChangeStoryboard(image);
            if (sb != null) // на всякий случай проверим
                sb.Begin(image); // анимация всегда будет назначаться непосредственно image
        }
    }


Далее импортим неймспейс в XAML и можем использовать таким образом:
Код

        <Image Source="{Binding MyBitmapSource}">
            <ext:ImageLoad.ChangeStoryboard>
                <Storyboard>
                    <DoubleAnimation Storyboard.TargetProperty="Opacity" From="0" To="1" Duration="00:00:0.5" />
                </Storyboard>
            </ext:ImageLoad.ChangeStoryboard>
        </Image>


ну или так:
Код

        <?????.Resources>
            <Storyboard x:Key="imageChangedAnimation">
                <DoubleAnimation Storyboard.TargetProperty="Opacity" From="0" To="1" Duration="00:00:0.5" />
            </Storyboard>
        </?????.Resources>
        
        <Image Source="{Binding MyBitmapSource}" loc:ImageLoad.ChangeStoryboard="{StaticResource imageChangedAnimation}" />


Вроде так будет удобно и можно в стилях все делать без проблем.


--------------------
Если тебе плюют в спину, значит ты впереди...
PM   Вверх
Rohoss
Дата 9.5.2011, 19:15 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Начальник интернета
***


Профиль
Группа: Завсегдатай
Сообщений: 1308
Регистрация: 9.10.2006
Где: Matrix

Репутация: 4
Всего: 18



-Mikle-, спасибо, действительно хорошее решение  smile 


--------------------
Файловый менеджер Explorer.Net скачать  video
PM ICQ   Вверх
Rohoss
Дата 9.5.2011, 20:29 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Начальник интернета
***


Профиль
Группа: Завсегдатай
Сообщений: 1308
Регистрация: 9.10.2006
Где: Matrix

Репутация: 4
Всего: 18



Однако этот вариант не годится, если мы отслеживаем изменение в нашей, и на это изменении вешаем анимацию. У нас ведь в ViewModel нет DependencyProperty, да и заводить их там не правильно. А смысл отслеживать изменения не в самом контроле а в ViewModel, и на них вешать анимацию есть. Вот например, у нас текстбокс биндится к полю в ViewModel. Мы отлавливаем изменении текста для анимации. Если мы вешаем анимацию на TextСhanged, то при вводе текста мы получим много проблем. Анимация нам может даже не дать его нормально набрать, а вот если отслеживаем изменение в ViewModel, может быть совершенно другая история...


--------------------
Файловый менеджер Explorer.Net скачать  video
PM ICQ   Вверх
-Mikle-
Дата 9.5.2011, 21:51 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Невидимка Vingrad'а
***


Профиль
Группа: Экс. модератор
Сообщений: 1672
Регистрация: 22.6.2003
Где: Казахстан, Астана

Репутация: 13
Всего: 59



Цитата(Rohoss @  9.5.2011,  23:29 Найти цитируемый пост)
 У нас ведь в ViewModel нет DependencyProperty, да и заводить их там не правильно. 

Верно, нет и не надо.

Цитата(Rohoss @  9.5.2011,  23:29 Найти цитируемый пост)
А смысл отслеживать изменения не в самом контроле а в ViewModel, и на них вешать анимацию есть

Если честно, я вот прям не понял разницы. Особенно если речь идет об ImageSource.

Цитата(Rohoss @  9.5.2011,  23:29 Найти цитируемый пост)
Вот например, у нас текстбокс биндится к полю в ViewModel. Мы отлавливаем изменении текста для анимации. Если мы вешаем анимацию на TextСhanged, то при вводе текста мы получим много проблем. Анимация нам может даже не дать его нормально набрать, а вот если отслеживаем изменение в ViewModel, может быть совершенно другая история... 

Если повешать анимацию на изменение данных, а затем у Binding выставить свойство UpdateSourceTrigger=PropertyChanged, то получим точно такую же историю как и с TextChanged. Конкретно в этом случае, правильно было бы вешаться на LostFocus. Вообще, я считаю, анимация это дело представления, а значит в первую очередь стараться подходить со стороны представления, а уже потом, со стороны всего остального.

Другое дело, если анимация на Image должна запускаться не при изменении чего-то из Image, а при изменении значения какого-то вообще другого свойства модели представления, тогда да. В последнем случае, конечно же, мы не в состоянии отследить эти данные и их нужно выносить на конкретный уровень. В общем, опять зависит все от задачи. Попытка ввести строгие правила в отношении этого, приведет в итоге к плохозакодированному коду (плохозамасленное масло smile). ИМХО.

Добавлено через 5 минут и 29 секунд
Кстати, в примере который я приводил выше, все можно было бы сделать еще красивее, если сделать присоединенное событие, которое бы называлось ImageSourceChanged. Тогда все можно было бы делать через триггер так, как будто это событие является родным для Image.


--------------------
Если тебе плюют в спину, значит ты впереди...
PM   Вверх
Rohoss
Дата 9.5.2011, 22:01 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Начальник интернета
***


Профиль
Группа: Завсегдатай
Сообщений: 1308
Регистрация: 9.10.2006
Где: Matrix

Репутация: 4
Всего: 18



Цитата(-Mikle- @  9.5.2011,  21:51 Найти цитируемый пост)
Вообще, я считаю, анимация это дело представления, а значит в первую очередь стараться подходить со стороны представления, а уже потом, со стороны всего остального.

Ну тут с вами сложно не согласится  smile 

Цитата(-Mikle- @  9.5.2011,  21:51 Найти цитируемый пост)
Если повешать анимацию на изменение данных, а затем у Binding выставить свойство UpdateSourceTrigger=PropertyChanged, то получим точно такую же историю как и с TextChanged.

Ну если так то да, а если у нас есть кнопка сохранить, тогда нет

А вообще если у нас есть целая группа контролов привязанных к ViewModel. Можно в таком случае отслеживать изменения какого то одного контрола и анимировать все. Но что если данные контрола не изменятся, значение свойств будут совпадать. То есть, с нашей группы контролов, при изменении в ViewModel, значения свойства не изменится из за совпадения, тогда анимация не выполнится во всей группе, хотя во всех контролов значение изменится.

Добавлено через 6 минут и 25 секунд
Цитата(-Mikle- @  9.5.2011,  21:51 Найти цитируемый пост)
Кстати, в примере который я приводил выше, все можно было бы сделать еще красивее, если сделать присоединенное событие, которое бы называлось ImageSourceChanged. Тогда все можно было бы делать через триггер так, как будто это событие является родным для Image. 

Угу, у меня тоже такая идея вначале была - но я не знал как реализовать... И похоже всё получилось бы очень сложно и много было бы кода  smile 


--------------------
Файловый менеджер Explorer.Net скачать  video
PM ICQ   Вверх
  
Ответ в темуСоздание новой темы Создание опроса
1 Пользователей читают эту тему (1 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | WPF и Silverlight | Следующая тема »


 




[ Время генерации скрипта: 0.0785 ]   [ Использовано запросов: 21 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.