
- •#024 – Знакомство с wpf/e
- •#023 – Введение в wpf, reloaded…
- •#022 Введение в Microsoft Interactive Designer rc1
- •#021 Применение 3d в wpf - Часть 2
- •#020 Применение 3d в wpf - Часть 1
- •#019 Введение в возможности 3d на wpf
- •#018 Размещение контрола net 2.0 на форме wpf
- •Imports System.Windows.Forms.Integration
- •#019 Введение в возможности 3d на wpf
- •#017 Первое Web-приложение / Подробнее о Grid / Элемент Frame
- •#016 Exe, xbap, xaml? - Все равно!
- •#015 Рисуем при помощи Visual Brush
Создаем контекстно-зависимое WPF-приложение #024 – Знакомство с WPF/E #023 – Введение в WPF, reloaded… #022 Введение в Microsoft Interactive Designer RC1 #021 Применение 3D в WPF - Часть 2 #020 Применение 3D в WPF - Часть 1 #019 Введение в возможности 3D на WPF #018 Размещение контрола NET 2.0 на форме WPF #017 Первое Web-приложение / Подробнее о Grid / Элемент Frame #016 EXE, XBAP, XAML? - Все равно!
Создаем контекстно-зависимое WPF-приложение
Начинаем
цикл публикаций, призванных помочь
начинающим программистам в создании
контекстно-зависимых приложений для
Windows 7. Об этом много говорили на PDC да и
мы неоднократно писали о этом новом
классе приложений. Пользователи Windows
7 build
6801 могли заметить появление в гаджете
погоды опции автоматического определения
местоположения компьютера. И сегодня
у вас появилась уникальная возможность
попробовать себя в создании подобных
приложений.
Я решил немного поиграть
с Windows Location Platform, входящей в состав
Windows 7 build 6801, которая была роздана
посетителям конференции PDC 2008, и решил
попробовать создать свое WPF-приложение,
которое показывало бы карту Virtual Earth и
мое местоположение на ней.
В сборке
6801 всем СОМ-классы Location API обозначены
как ThreadingModel = Free (MTA). Поэтому, для того
чтобы вызвать их из другой потоковой
модели (STA), придется прибегнуть к
промежуточным классам. Похоже, что
сборка, генерируемая VS (LocationDispLib.dll), не
включает в себя эти самые промежуточные
классы для COM-распределения. Таким
образом, для получения доступа к Location
API нам необходимо использовать другой
поток, который позволит использовать
эти данные в нашем WPF-приложении.
Что
нужно для создания приложения
Windows 7 build 6801
Visual Studio 2008 SP1
RibbonControlsLibrary (CTP)
WPF-контрол Virtual Earth от Майка Толти (Mike Taulty)
Virtual GPS (от HOL с PDC)
Сценарии, которые позволяет реализовать приложение
Показывать карту на базе местоположения пользователя
Показывать схему движения, автоматически обновляя данные
Очищать карту
Запускаем приложение. Нажимаем на кнопку Show Me on Map, Windows Location Platform получает координаты, приложение отмечает текущее местоположение на карте. Приложение отслеживает перемещения и ежесекундно отмечает их. Как это реализовано Windows Location Platform API представлены COM- и Win32-объектами. Для упрощения программирования мы воспользуемся COM-версией API, которая внедрена в файл LocationDisp.dll в папке %Windir%\System32\ (в x86-версии). Для использования данного API нам необходимо добавить в проект ссылку на эту библиотеку. 1. Так как API запускаются в режиме MTA, а основное WPF-приложение в STA, нам нужно использовать отдельный поток для того, чтобы наше приложение могло получить информацию от API.
BackgroundWorker m_worker предназначен для обработки изменения местоположения, а второй BackgroundWorker m_workerStatus добавляем в определение Window1:
Код:
BackgroundWorker m_worker = new BackgroundWorker(); BackgroundWorker m_workerStatus = new BackgroundWorker(); private LatLongReport m_report = new LatLongReport(); private LocationPlatformStatus m_status = new LocationPlatformStatus(); DispatcherTimer m_timerAutoTracking = new DispatcherTimer(); DispatcherTimer m_timerLocPlatformStatus = new DispatcherTimer(); bool m_useAutoTracking = false;
Таймеры будут использоваться для обработки изменения местоположения (m_timerAutoTracking). LatLongReport - .NET упаковщик для класса DispLatLongReport из Interop.LocationDisp.dll, которая была создана из LocationDisp.dll силами Visual Studio. Она необходима для того, чтобы несколько упростить COM-функцию, вызываемую в .NET-приложении.
В конструкторе Window1 мы инициализируем и фоновые исполнители, и таймеры:
Код:
public Window1() { InitializeComponent(); m_worker.DoWork += new DoWorkEventHandler(worker_DoWork); m_worker.RunWorkerCompleted += new RunWorkerCompletedEventHandler(worker_RunWorkerCompleted); m_workerStatus.DoWork += new DoWorkEventHandler(m_workerStatus_DoWork); m_workerStatus.RunWorkerCompleted += new RunWorkerCompletedEventHandler (m_workerStatus_RunWorkerCompleted); m_timerAutoTracking.Interval = new TimeSpan(0, 0, 0, 0, 1000); m_timerAutoTracking.Tick += new EventHandler(m_timer_Tick); m_timerLocPlatformStatus.Interval = new TimeSpan(0, 0, 0, 0, 1000); m_timerLocPlatformStatus.Tick += new EventHandler(m_timerLocPlatformStatus_Tick); // enabling Status Timer m_timerLocPlatformStatus.Start(); }
Здесь мы просто инициализировали асинхронные обработчики событий DoWork и RunWorkerCompleted для обоих исполнителей Background Worker, настров интервал в 1 секунду для таймеров и обработчиков их событий.
Вызов Windows Location Platform API Нажав кнопку Show Me On Map, пользователь инициализирует в приложении соответствующую команду и она запускает асинхронный исполнитель Background Worker m_worker:
Код:
public void ShowMeOnMapCommand_Executed(object sender, ExecutedRoutedEventArgs e) { try { m_worker.RunWorkerAsync(); } catch { // some times it can't do the job at 1 sec } }
Тут, однако, есть маленькая проблема. Так как мы не подписываемся на события через Location API, но при этом вызываем их, используя таймеры, исполнители Background Worker могут столкнуться с проблемой, при которой они не успели завершить свою работу. Чтобы не усложнять приложение, я решил добавить здесь блок. RunWorkerAsync() включает событие DoWork() из фонового исполнителя m_worker:
Код:
void worker_DoWork(object sender, DoWorkEventArgs e) { LatLongReportFactoryClass factory = new LatLongReportFactoryClass(); m_report = new LatLongReport(factory.LatLongReport); }
Именно здесь происходит реальное обращение к Windows Location API. То есть нам необходимо сослаться на LatLongReportFactoryClass и получить от него LatLongReport, который и будет использоваться в приложении. В действительности, первое, что нам необходимо сделать - проверить поле LatLongFactoryClass.Status, чтобы убедится, что сенсоры доступны и работают.
Когда фоновый исполнитель m_worker завершит получение LatLongReport, нам нужно создать на карте новый PushPin, дать ему текущие координаты и показать на карте.
Код:
void worker_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e) { if (e.Cancelled) { //Cancelled } else if (e.Error != null) { //Exception Thrown } else { //Completed PushPin pushPin = new PushPin(); pushPin.Latitude = m_report.Latitude; pushPin.Longitude = m_report.Longitude; t his.VirtualEarth.PushPins.Add(pushPin); pushPin.CenterInMap(); } }
В данном методе мы центрируем карту, чтобы созданная отметка показывалась по центру Virtual Earth. В случае если сенсоры присутствуют, включены и доступны, нажатие кнопки Show Me on Map покажет в центре карты Virtual Earth нашу позицию.
2. Для реализации автоматического обновления местоположения мы используем таймер Dispatcher Timer m_timer, который автоматически будет запускать Background Worker m_worker для получения информации о местоположении. Для этого мы просто добавим в обработчик вызова кнопки Show/Stop showing My Trip on Map Automatically вызов Start/Stop m_timer, а для отметки на карте - m_worker.RunWorkerA. 3. Чтобы очистить карту, требуется вызвать метод “Clear” из коллекции контролов “PushPins”. Теперь вы знаете, как вызывать Windows 7 Location Platform API с целью получить информацию о местоположении пользователя, и использовать ее в WPF-приложении. Вот, собственно, и все. В следующий раз мы поговорим о том, как проверить статус платформы, о том, что делать в случае, если доступ запрещен, и что делать с провайдером, используемым по умолчанию. Источник: http://blogs.msdn.com/semantics Перевод: Zloy Kak Pё$
#024 – Знакомство с wpf/e
Не
так давно произошел долгожданный релиз
набора библиотек Microsoft .NET
3.0
и, возможно, появилась возможность
вникнуть более подробно в привнесенные
этим набором новшества. Возможно, но не
тут- то было. Microsoft в серьез взялась за
популяризацию Windows
Presentation Foundation
–
и вот, с пылу с жару, новый (или не совсем
новый) продукт WPF-E. E – это от английского
“everywhere” – тобишь WPF
везде.
Отбросим мысли о том, что софтверный
гигант решил таким образом всего лишь
задавить (или все-таки слегка потеснить?)
Flash и подумаем о том, что же означает это
«везде». А означает это следующее –
разработчики веб-сайтов смогут не только
создавать стандартные, «тяжелые»
XBAP-приложения (для работы с которыми уж
очень нужен IE…) но и «легкие», основанные
на XAML страницы. И при чем тут «везде»? А
при том, что вместе с технологией WPF-E,
компания выпустила несколько плагинов
(объемом всего-то в один мегабайт), при
помощи которых просмотр WPF-E контента в
IE, Firefox и даже на компьютерах Apple Macintosh и
даже на мобильных устройствах яйца
выеденного стоить не будет. Поистине
сильно желание Microsoft сразиться с Flash и,
надо заметить, некоторые энтузиасты
уже сделали абсолютно идентичные проекты
на Flash и WPF-E и последний ничуть не уступает
первому. Мало того, есть масса способов
объединить обе технологии в рамках
одного web-сайта, и не только объединить,
но даже заставить взаимодействовать.
Действительно, огромное поле для
творчества.
Итак, давайте создадим
очень простую страницу типа «Hello World»,
чтобы познакомиться с технологией
WPF/E.
Что нам необходимо? Прежде всего
скачать Silverlight. Во вторых, нам понадобится
пустая html-страница, например, с таким
содержанием:
Код:
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en"> <head> <title>A Sample HTML page</title> </head> <body> </body> </html>
И в третьих, нам потребуется текстовый редактор, например «Блокнот» прекрасно подойдет. После того, как вы подготовили все вышеуказанные средства, Вам понадобится небольшой файл, основанный на JavaScript, который Microsoft любезно подготовила для разработчиков, с целью организовать очень быстрый и простой способ внедрить WPF-E контент на любую html-страницу. Скачайте архив с этим файлом тут: http://www.thevista.ru/datas/users/2180-aghost.zip , распакуйте архив и разместите вышеупомянутый файл, который имеет имя «aghost.js» в директории, в которой вы подготовили свою html-страницу. Теперь, нам необходимо подключить этот файл к нашей странице, для этого откройте Вашу страницу в блокноте и внесите следующую строку в секцию <head> вашего html-файла:
Код:
<script type="text/javascript" src="aghost.js"></script>
В моем случае код страницы будет выглядеть так:
Код:
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en"> <head> <title>A Sample HTML page</title> <script type="text/javascript" src="aghost.js"></script> </head> <body> </body> </html>
Теперь нам необходимо создать область в которой будет работать наш WPF-E элемент. Это очень просто. Добавьте этот код внутрь секции <body> Вашего html-файла:
Код:
<!—Здесь будет работать WPF/E ActiveX контрол--> <div id="agControl1Host"> </div>
Создав таким образом область для работы контрола, необходимо описать этот самый контрол – сделать это, так же, довольно просто. Нижеизложенный код необходимо добавить внутрь блока <body>, но ниже вышеописанных тегов <div></div>:
Код:
<script type="text/javascript"> // Создаем WPF/E ActiveX контрол. // Используя данный метод мы избавляем пользователя от необходимости кликать по // ActiveX контролу прежде чем WPF/E получит информацию от пользователя new agHost( "agControl1Host", // hostElementID ( элемент HTML element который мы описали выше в теге <div>) "agControl1", // ID контрола WPF/E ActiveX которого мы создаем "300px", // ширина (width) "300px", // высота (height) "#D6D6D6", // цвет фона (backgroundcolor) null, // SourceElement (имя script-тэга содержащего xaml) "SampleProject.xaml", // файл источник контента (source file) "false", // Без окна (IsWindowless) "30", // Скорость кадров (MaxFrameRate) null // OnError handler (метод отлова ошибок) ); // также создаем глобальную переменную для WPF/E ActiveX контрола, // которую мы можем использовать, чтобы найти xaml элементы var agControl = document.getElementById("agControl1"); </script>
Итак, возможно Вам покажется, что данный код несколько громоздкий, но на самом деле он не содержит ни одной лишней строки. Вы уже поняли, что мы применяем комбинированный HTML+Sсript язык, для описания. Думаю, разобраться в нем не составит проблемы. Тем не менее, внимательно изучите комментарии, которые я внес в код, для Вас. Эти комментарии помогут Вам максимально быстро разобраться с тем, как правильно определить отображающий элемент (под отображающим элементом я понимаю ту область, которая будет отображать WPF-E контент). Итак, внимательный читатель обратил внимание на параметр «Source File» - и правильно, так как именно этот параметр ссылается на xaml-файл, в данном случае с именем «SampleProject.xaml», который и содержит замечательный WPF-контент. Чтож, создайте пустой xaml-файл (для этого достаточно создать текстовый документ и изменить расширение с «txt» на «xaml») c нужным именем и разместите его в директории, в которой находится ваша html-страница. Вы уже знакомы с тем, какие элементы используются для рисования в XAML. Все, что нужно добавить, это то, что контент WPF-E всегда размещается внутри контейнера <Canvas>, в другом все идентично. Для того, чтобы закончить нашу страницу нарисуем кое-что в нашем xaml-файле. Внесите в него такой код:
Код:
<Canvas Width="300" Height="300" xmlns="http://schemas.microsoft.com/client/2007" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"> <Ellipse Height="200" Width="200" Canvas.Left="30" Canvas.Top="30" Stroke="Black" StrokeThickness="10" Fill="LightBlue"/> </Canvas>
Сохраните
все документы и запустите Вашу
страницу:
Поздравляю!
Вы только что создали свою первую
страницу на базе WPF-E. Что еще можно
добавить? Если Вы хотите разместить на
странице несколько независимых контролов
для отображения XAML – не забудьте
присвоить каждому из них уникальное
имя. Что? Вы не видите содержимого данной
страницы? Это может быть только потому,
что вы забыли установить плагин для
Вашего броузера.