Metro Developers Digest #6

А вот и он – шестой выпуск нашего дайджеста! Напомним, предыдущие выпуски можно всегда прочесть и освежить.
Со времени выхода прошлого дайджеста нам были интересны следующие статьи:

  1. Ох уж эти Binding-и
  2. Советы для любителей Panorama
  3. Как правильно отключить повоторы LiveTile c задником
  4. Исходные коды очередного приложения для WP7
  5. Realtime Google Analytics для Windows Phone
  6. Асинхронный аналог MessageBox, с плюшками
  7. MarketplaceDetailsTask для Windows 8 Metro приложений
  8. Отчет по ежедневным продажам ваших приложений в zTop


И другие интересные новости. Начинаем!

Что мы нашли интересного про cвязывание данных (Binding):
Недавно столкнулись с проблемой биндинга через Attached Property, тип которого был задан через базовый класс. Никаких ошибок биндинга не получали. Данный биндинг тихо и мирно игнорировался. Оказалось, что не стоит задавать тип Attached Property, указав базовый тип ожидаемого объекта.

И еще одна gotcha – если биндинг указывает на элемент (пусть элемент1) через ElementName или Source, и DataContext родительского элемента для элемента1, то эти изменения не будут переданы в Binding, и привязка данных не обновиться. Однако, если изменится DataContext элемента1, то изменения будут переданы.
Так что, если встречаетесь со странным поведением при привязке данных, прочтите и эту статью – Workaround for a Silverlight data binding bug affecting various scenarios – including DataGrid+ContextMenu

Теперь для любителей элемента Panorama.
Liwen Guo предложил отличный способ сделат smooth start experience для приложений с панорамой.
Суть подхода проста – сделать “скриншот” последнего айтема в панораме (правого) и сдвинуть его на 48 пикселей вправо, остальное (пустое) пространство нужно заполнить фоновой картинкой 🙂
Видео результата и подробности советуем прочесть на сайте автора.

Помощь в скрытии части панорамы динамически поможет Kevin Goose. В своем блоге он описыват, каким своебразным способом можно достить нужного поведения. Мы считаем, что такой магией заниматься не стоит. Если у вас иногда не видна часть панорамы (один элемент из 3-4), то лучше в таких ситуациях там показывать советы/помощь/whatever. Если у вас 2 элемента, и один из них нужно иногда скрывать – вам не нужна панорама.

Однажды сделав свой основной тайл живым, отключать его придется с читом (чтобы он не вращался сам в себя):
newTileData.BackBackgroundImage = new Uri(“doesntexist.png”, UriKind.Relative);
Указав null или невалидную ссылку вы получите эффект когда тайл будет вращаться “сам в себя”. Используйте несуществующее имя файла!

В прошлом выпуске мы рассказали о публикации некоторой части кода приложения 4th and Mayor. Из очень полезного кода, на гитхабе есть окно диалога для шаринга информации. Пользователю предоставляется выбор из соц сетей, почты или сообщений. Напомним, что подобного стандартного диалога в SDK нет, однако он широко используется встроенными приложениями. Такой диалог можно встретить в IE, если в меню выбрать “отправить ссылку”(“share page”).

Очередное приложение для WP7, которое опубликовало исходные коды – это справочник рецептов тайской еды (какое совпадение!) Автор Patrick Kalkman рассказывает о полной архитектуре приложения (от клиента до базы данных и сервисов) и о разработке деталей, например, ротация фонового изображения в панораме, использование различных провайдеров рекламы и тп. Рекомендуем к прочтению. codeproject.com/Articles/409470/Weekly-Thai-Recipe-for-Windows-Phone

Мы уже упоминали в одном из своих выпусков, что использование TransitionFrame с прозрачным фоном улучшает производительность. Решили попробовать в одном из наших проектов и не пожалели!
RootFrame = new TransitionFrame() { Background = new SolidColorBrush(Colors.Transparent) };
Благодаря этой строчке приложение теперь отрисовывает 3.5 – 4 вместо 5 – 5.5 экранов за каждый фрейм.

Тут все понятно и без дополнительных слов.


Добавим лишь, что realtime tracking доступен в Google Analytics как бета-версия с сентября 2011 года.

Интересные наблюдения о маркетинге приложения WP7 и о значении имени. Как корабль назовешь, так он и поплывет.
http://dotnetapp.com/blog/2012/06/28/application-name-matters/

Предлагают поменять MessageBox на асинхронную версию. А что, я за! Не нравится сидеть в дебаге и ждать, пока кликнуть на мессаджбокс. Кроме того, в бонус получаем возможность зафокусить кнопку, выключить вибро и звук, передавать object в качестве состояния и так далее.

В сегодняшнем выпуске про Windows 8 только один пункт.
Алан Менделевич, автор одной из популярных рекламных сетей для wp7, поделился своими наработкам по интеграции вашего windows 8 приложения в экосистему Windows Store. Оказывается, простой замены MarketplaceDetailsTask на Windows8 нет. Зато уже есть решение. Спасибо, Алан!

И теперь про AppHub. В AppHub есть интересная и не известная широким массам возможность – при заливке XAP система определяет наличие кода для отладки (Debug Code) в вашем приложении.

Продолжая тему AppHub, нам давно не хватало возможности посмотреть ежедневные продажи наших приложений. И вот не прошло и года полтора с момента выхода первой версии zTop, как мы наконец решились сделать соответствующий отчет, который Вы всегда сможете сгенирировать и для своих приложений. До сих пор не можем понять, почему AppHub такой скупой на отчетность.

Ну и секция “Креатив в стектрейсах” 🙂
Если в отчетах встречаете следующий бессмысленный stacktrace:
System.ArgumentException: The parameter is incorrect.
at MS.Internal.XcpImports.MethodEx(IntPtr ptr, String name, CValue[] cvData)
at MS.Internal.XcpImports.MethodPack(IntPtr objectPtr, String methodName, Object[] rawData)
at MS.Internal.XcpImports.TouchFrameEventArgs_GetPrimaryTouchPoint(TouchFrameEventArgs args, UIElement relativeTo)
at System.Windows.Input.TouchFrameEventArgs.GetPrimaryTouchPoint(UIElement relativeTo)
at Dial.*.Touch_FrameReported(Object sender, TouchFrameEventArgs e)
at System.Windows.Input.Touch.OnTouch(Object sender, TouchFrameEventArgs e)
at MS.Internal.JoltHelper.RaiseEvent(IntPtr target, UInt32 eventId, IntPtr coreEventArgs, UInt32 eventArgsTypeIndex)

то решение нам поможет найти Zhu Xianzhong в своем блоге (только не плачьте, что ничего не понимаете – Google Translate, да и C# везде одинаков).
Причина ошибки, в общем, проста – нужно проверять sender на null перед вызовом GetPrimaryTouchPoint
if (sender == null)
return;
var point = e.GetPrimaryTouchPoint(LayoutRoot);

p.s. а вы знали, что с Resharper нажатие ctrl + D дублируют текущую строку кода? Мы противники копипаста, но порой бывает удобно 😉