| Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате |
| Форум программистов > WPF и Silverlight > Бегущая строка |
| Автор: AleksPingvin 24.5.2011, 07:00 |
| Доброе утро, друзья! Продолжаю задавать глупые вопросы по WPF..(предварительно разумеется гуглю). Хотелось бы услышать ваше профессиональное мнение по реализации одного компонента. Согласно поставленной мне задаче в программе должна быть бегущая строка. По скольку она должна быть довольно сильно стилизована (сложный фон, двигается не только текст но и пиктограммы), то я решил делать это следующим образом. Создал свой класс CreepLine унаследовав его от Canvas, объявил нужные DependencyProperty, перегрузил GetVisualChild, VisualChildrenCount. Объявил объект DrawingVisual, который добавляю на канву через AddVisualChild и AddLogicalChild, на нем я и хочу рисовать все что мне надо. Далее я хочу отрендерить данные и clip-ать их по нужному прямоугольнику. А в анимации менять свойство которое будет отвечать за смещение прямоугольника обрезки. Вопрос на сколько оправдана такая реализация и вообще возможно ли она? Не будет ли проблем с производительностью? Быть может есть более "гуманный" способ реализации бегущей строки? К сожалению в интернете я ни где не смог найти реализации бегущей строки на wpf, разве что только в текстовом поле DataGrid, но мне это ведь не катит... С Уважением, Александр |
| Автор: AleksPingvin 24.5.2011, 13:48 |
| Буду ждать с нетерпением. |
| Автор: AleksPingvin 24.5.2011, 21:16 |
| Кстати попробовал реализовать идею и неожиданно столкнулся с проблемой создания пустого изображения. Хочу сделать следующее: 1) Рассчитать ширину изображения, путем сложения ширины текста (FormattedText мне в помощь) и пиктограм + margin. 2) Создать изображение и отрисовать на нем текст и строку 3) Согласно текущему смещению отрендерить путем Clipin-ga в методе OnRender на мой компонент . Вот ни как не найду нужные классы для пункта 2.. не подскажете ли? Видел пример с использованием Canvas, которая потом подается в RenderTargetBitmap , но что-то мне подсказывает, что это не правильный путь.... |
| Автор: DenWPF 24.5.2011, 22:27 |
| Не понимаю в чем сложность. берете текст бокс убераете у него стили. строку в цикле по символу вызываете... |
| Автор: AleksPingvin 25.5.2011, 02:04 |
| Мне не нужен текстбокс. У меня бегущая строка со сложным фоном, пиктограммами и плавной (а не сдвиг по символу) анимацией. |
| Автор: -Mikle- 25.5.2011, 06:07 |
| AleksPingvin, в моей реализации любой контент можно прокручивать, это подходит? Может седня вечером работы меньше будет, напишу. |
| Автор: AleksPingvin 25.5.2011, 07:30 |
| -Mikle-, если она исполняет свою главную роль - текст бежит и можно использовать пиктограмки в нем, то да. Впрочем все равно опишите идею, лишним не будет. А заодно пока не подскажете ли как все же для общего развития, как мне программно (а не загрузив из файла) создать изображение на котором я потом смогу программно отрисовать все что захочу |
| Автор: DenWPF 25.5.2011, 15:12 | ||||
| Я конечно не сильно понял, ну а такой вариант не подходит? если нет, то есть пример того чего ты хочешь?
|
| Автор: AleksPingvin 25.5.2011, 16:18 |
| Код не запускал, ибо на работе, но на сколько я вижу: 1) Бежит только текст. Я в третий раз говорю - нужно иметь возможность задавать в качестве объекта движения не только текст, но и пикторграммы. Например: Игра начинается в <пиктограма будильника> 12.00 бла бла бла. 2) Когда строка кончается, то дальше она идет заново не ожидая того, когда ее остаток дойдет до конца. Иными словами если строка "Привет, я дядя Степа!" и вся фраза не влазит в ширину строки, то будет выглядеть так: "вет, я дядя Степа! При" |
| Автор: DenWPF 25.5.2011, 17:11 |
| бежит не текст, а Label т.е Контрол, можно любой контрол так. Сделай обертку с областью видимостью. ладно, пусть -Mikle- напишет как у него. |
| Автор: -Mikle- 25.5.2011, 18:46 | ||||||||
Ну именно так и сделано у меня. Я решил смотреть в наш контрол и написать новый, но только изрядно урезанный вариант. Тем самым я и весь основной код не выложу (сохраню права на код), но в то же время то что требуется именно топикастеру реализую. В связи с копи-пастами из более навороченного контрола некоторая логика, возможно, будет излишней. Правьте сами, кому не нравится Контрол делался для силверлайта, но я не предвижу никаких проблем сделать то же самое на WPF. Итак... Создаем Templated Control и даем имя CreepLine. Студия нам создает CreepLine.cs и Generic.xaml (в нем будет определяться шаблон контрола). Далее меняем код класса на вот это:
Открываем Generic.xaml и находим там стиль для вновь созданного контрола. Редактируем его и приводим в такой вид:
Вот и все. Этот контрол выполняет нужную функцию, а именно, анимирует слева на право любой контент. Свойство IsEnabled говорит о том бежит ли контент или стоит. Свойство InitialDelay задает паузу, перед тем как контент начнет бежать (тут наверное лишнее для этой задачи). Вот пример использования:
Как видно, можно расположить абсолютно любой контент, с навороченными бэкграундами, фореграундами, форматированием, картинками, да хоть видеоролик сюда вставляй. |
| Автор: AleksPingvin 25.5.2011, 19:18 |
| -Mikle-, супер! Попробую утром перекопипастить и потестить ваш компонент) Если возникнут вопросы - обязательно их задам Кстати а "выбег" содержимого начинается с краю или он сразу появляется а только потом начинает двигаться? |
| Автор: -Mikle- 25.5.2011, 20:55 | ||
Ну вот завтра и увидишь Не дорассказал еще про свойство PixelsPerSecondSpeed - оно задает скорость перемещения в пикселах (на сколько пикселов двинется контент за одну секунду), по умолчанию стоит 75. Свойства StartContentAtRight, EndContentAtLeft, EndContentAtRight и Duration - ридонли и служат для поддержки анимации в шаблоне контрола. Ну конечно задать значения этих свойств можно, только не из XAML. Да и незачем стремиться к этому, так как они все равно снова пересчитаются при любом изменении. В WPF можно объявить ридонли депенденси свойства и тогда они действительно будут ридонли, а сильверлайт пока не поддерживает такие. |
| Автор: AleksPingvin 26.5.2011, 05:51 |
| -Mikle-, ты меня убьешь... но моя VS 2010 не умеет создавать Template Control-ы... нет у нее такого пунктика( Вот User Control да)... я ее даже обновил и сдк поставил и нифига. |
| Автор: -Mikle- 26.5.2011, 06:32 |
| Не убью |
| Автор: AleksPingvin 26.5.2011, 07:24 | ||
| Сделал просто файл ресурсов вставил туда стиль и создал класс CreepLine разместив твой код там... разместил компонент где надо и... ничего нет( просто белое пустое место( ни текста ни анимации... ни даже фона. видимо xaml надо как-то поиному делать всеже надо... СustomControl попробую вечером, что то он не создается.. визуалка эксепшен выдает( Добавлено @ 07:33 Гы. Забыл ресурс подрубить в окно.. но теперь ошибка RelativeSoure.. эксепшен т.е.
|
| Автор: DenWPF 26.5.2011, 08:09 |
| Если проект чистый залей его. |
| Автор: AleksPingvin 26.5.2011, 08:37 |
| Почищу.. но в принципе можно просто сделать пустой проект, добавить файл ресурсов, в который вставить код стиля приведенного Майклом и создать класс вставив его же исходники... а в главном окне вставить компонент... |
| Автор: -Mikle- 26.5.2011, 11:39 |
| Ну если у тебя не получится, я вечерком в WPF сам перенесу код и выложу сюда. Возможно это все таки из-за неполной совместимости WPF и Silverlight. |
| Автор: AleksPingvin 26.5.2011, 19:45 |
| Не получается( Ошибка и все тут( Вся надежда на тебя... |
| Автор: -Mikle- 27.5.2011, 08:08 | ||
| Да, выяснилось, что полной совместимости между WPF и Silverlight нету. В XAML коде надо сделать пару изменений: 1) RelativeSource нужно обязательно объявить с явно заданным режимом: RelativeSource={RelativeSource TemplatedParent} 2) Чтобы относительный источник был найден, биндинг должен (почему-то, в отличие от сильверлайт) находиться в зоне досягаемости визуального дерева. Чтоб этого достичь, можно перенести анимацию в ресурсы корневого элемента шаблона. В итоге, шаблон теперь выглядит вот так:
Код логики контрола остается без изменений. На всякий случай, прикрепляю солюшн с контролом и его тестовым экзешником. |
| Автор: AleksPingvin 27.5.2011, 08:53 |
| Век живи, дорогой Mikle! Спасибо тебе огромное! Вечером буду смотреть дома) |
| Автор: AleksPingvin 27.5.2011, 15:16 |
| Посмотрел, все работает) Жаль правда нельзя сделать так что бы не ждать полного пробега "хвоста", но это я попытаюсь заказчика убедить, что он не прав.... |
| Автор: -Mikle- 27.5.2011, 15:40 | ||
Если я правильно тебя понял, то вот тут:
в анимации есть привязка То к EndContentAtLeft (конец контента слева). Есть еще свойство EndContentAtRight (конец контента справа). Добавлено через 3 минуты и 27 секунд Если имеется ввиду что сразу после конца контента располагается его начало, то да, в текущей реализации нельзя, так как контент один. Но тебе никто не мешает сделать компонент, который рисует контент через вижуалбраш |
| Автор: AleksPingvin 27.5.2011, 17:13 | ||
Именно это я и имел ввиду.. а про VisualBrush... это идея! Я ведь ей на Adorner-е рисую... почему и тут не заюзать) |
| Автор: -Mikle- 27.5.2011, 20:33 |
| Да, можно попробовать поставить ей повторение и анимировать трансформацией, примененной к ней. |