{"id":732,"date":"2014-09-13T14:54:48","date_gmt":"2014-09-13T12:54:48","guid":{"rendered":"http:\/\/dev.bratched.fr\/fr\/?p=732"},"modified":"2014-09-13T14:54:48","modified_gmt":"2014-09-13T12:54:48","slug":"migration-du-longlistselector-en-universal-apps","status":"publish","type":"post","link":"https:\/\/bratched.com\/fr\/2014\/09\/13\/migration-du-longlistselector-en-universal-apps\/","title":{"rendered":"Migration du LongListSelector en Universal Apps"},"content":{"rendered":"<p>Apr\u00e8s les <a title=\"Migration vers 8.1 : Les fichiers de ressources resw\" href=\"http:\/\/dev.bratched.fr\/fr\/migration-vers-8-1-les-fichiers-de-ressources-resw\/\">ressources destin\u00e9es aux\u00a0traductions<\/a>, nous continuons le tour d&rsquo;horizon des \u00e9l\u00e9ments n\u00e9cessaires\u00a0pour migrer d&rsquo;un projet Windows Phone 8.0 en Universal apps.<\/p>\n<p><a href=\"http:\/\/dev.bratched.fr\/fr\/wp-content\/uploads\/sites\/2\/2014\/09\/LongListSelector-WP81.png\"><img decoding=\"async\" loading=\"lazy\" class=\"alignnone wp-image-735\" src=\"http:\/\/dev.bratched.fr\/fr\/wp-content\/uploads\/sites\/2\/2014\/09\/LongListSelector-WP81.png\" alt=\"LongListSelector WP81\" width=\"190\" height=\"317\" srcset=\"https:\/\/bratched.com\/fr\/wp-content\/uploads\/sites\/2\/2014\/09\/LongListSelector-WP81.png 480w, https:\/\/bratched.com\/fr\/wp-content\/uploads\/sites\/2\/2014\/09\/LongListSelector-WP81-180x300.png 180w\" sizes=\"(max-width: 190px) 100vw, 190px\" \/><\/a><\/p>\n<p>Le LongListSelector est un \u00e9l\u00e9ment de liste tr\u00e8s souvent utilis\u00e9 : Il est apparu en 8.0 mais existait d\u00e9j\u00e0 dans la version 7.0 sous forme d&rsquo;un composant tiers du Windows Phone Toolkit.<\/p>\n<p>Avec les Universal Apps, ce composant dispara\u00eet au profit d&rsquo;autres composants d\u00e9j\u00e0 pr\u00e9sents dans Windows 8.0 : Listbox, ListView, GridView.<\/p>\n<h1>Liste\u00a0Simple<\/h1>\n<p>Le cas le plus simple est lorsque LongListSelector est utilis\u00e9 en mode simple Liste (sans regroupement).<\/p>\n<p>Exemple de code :<\/p>\n<pre class=\"lang:default decode:true\">&lt;phone:LongListSelector\n   ItemsSource=\"{Binding AllItemsViewModel}\"    \n   IsGroupingEnabled=\"False\"\n   ItemTemplate=\"{StaticResource ItemTemplate}\" \/&gt;\n<\/pre>\n<p><!--more--><\/p>\n<p>Le IsgroupingEnabled=\u00a0\u00bbFalse\u00a0\u00bb indique ici qu&rsquo;il n&rsquo;y a pas de regroupement des item.<\/p>\n<ul>\n<li>Le templateItem met en forme les donn\u00e9es. La migration peut se faire tr\u00e8s facilement en rempla\u00e7ant le LongListSelector par un ListView ou m\u00eame un Listbox :<\/li>\n<\/ul>\n<pre class=\"lang:default decode:true\">&lt;ListView\n  ItemsSource=\"{Binding AllItemsViewModel}\"    \n  ItemTemplate=\"{StaticResource ItemTemplate}\" \/&gt;\n\n<\/pre>\n<p>Le ItemTemplate n&rsquo;a pas besoin d&rsquo;\u00eatre migr\u00e9 et reste identique.<\/p>\n<h1>Liste avec\u00a0regroupement<\/h1>\n<h2>Le regroupement et le IGrouping<\/h2>\n<p>Pour rappel, le regroupement des \u00e9l\u00e9ments passe par un objet ViewModel de type IGrouping&lt;KeyGroup, ItemViewModel&gt;.<\/p>\n<p>Ce regroupement est \u00e9galement n\u00e9cessaire pour un projet WP8.0 et Silverlight 8.1. La partie ci dessous est indispensable quelque soir le contr\u00f4le XAML utilis\u00e9 (WP8; WP8.1 Silverlight et WP8.1 XAML)<\/p>\n<p>Je prends l&rsquo;exemple tr\u00e8s simpliste d&rsquo;une liste de message que l&rsquo;on souhaite regrouper par Date.<\/p>\n<pre class=\"lang:default decode:true\">public class MessageViewModel\n{\n    public string Title { get; set; }\n    public DateTime FullDate { get; set; }\n    public DateTime DayDate { get { return FullDate.Date; } }\n}\n<\/pre>\n<p>Une liste poss\u00e8de d\u00e9j\u00e0 des messages :<\/p>\n<pre class=\"lang:default decode:true \">private List&lt;MessageViewModel&gt; _messages = new List&lt;MessageViewModel&gt;();<\/pre>\n<p>Pour g\u00e9rer un regroupement, il faut impl\u00e9menter une classe de type\u00a0IGrouping&lt;KeyGroup, ItemViewModel&gt;<\/p>\n<p>Ce qui peut \u00eatre d\u00e9fini en utilisant toujours ce m\u00eame mod\u00e8le :<\/p>\n<pre class=\"lang:default decode:true\">public class Group&lt;Tkey, TElement&gt; : List&lt;TElement&gt;\n{\n    public Tkey Key { get; set; }\n    public Group(IGrouping&lt;Tkey, TElement&gt; group)\n        : base(group)\n    {\n        this.Key = group.Key;\n    }\n\n    public override bool Equals(object obj)\n    {\n        Group&lt;Tkey, TElement&gt; that = obj as Group&lt;Tkey, TElement&gt;;\n        return (that != null) &amp;&amp; (this.Key.Equals(that.Key));\n    }\n\n    public override int GetHashCode()\n    {\n        return Key.GetHashCode();\n    }\n\n}<\/pre>\n<p>&nbsp;<\/p>\n<p>Exemple d&rsquo;utilisation de la liste dans le ViewModel :<\/p>\n<pre class=\"lang:default decode:true\">private List&lt;Group&lt;string, MessageViewModel&gt;&gt; _messagesByGroup = new List&lt;Group&lt;string, MessageViewModel&gt;&gt;();\n        \npublic List&lt;Group&lt;string, MessageViewModel&gt;&gt; MessagesByGroup { get {return _messagesByGroup; }}<\/pre>\n<p>La propri\u00e9t\u00e9 en \u00ab\u00a0public\u00a0\u00bb est indispensable pour le Binding.<\/p>\n<p>Une requ\u00eate Linq permet\u00a0de g\u00e9n\u00e9rer ce regroupement :<\/p>\n<pre class=\"lang:default decode:true \">var q = from messagevm in _messages\n                    orderby messagevm.DayDate descending, messagevm.Title\n                    group messagevm by messagevm.DayDate.ToString() into c\n                    select new Group&lt;string, MessageViewModel&gt;(c);\n            _messagesByGroup = q.ToList();<\/pre>\n<p>(Fin du rappel et de la partie commune)<\/p>\n<h2>Utilisation en XAML pour WP8.0 WP8.1 Silverlight<\/h2>\n<pre class=\"lang:default decode:true\">&lt;phone:LongListSelector       \n        ItemsSource=\"{Binding MessagesByGroup}\"\n        GroupHeaderTemplate=\"{StaticResource MessageGroupHeader}\"       \n        ItemTemplate=\"{StaticResource ItemTemplate}\"      \n        IsGroupingEnabled=\"True\"       \n        HideEmptyGroups =\"true\"\/&gt;<\/pre>\n<ul>\n<li>GroupHeaderTemplate : Mod\u00e8le pour la partie regroupement qui sera r\u00e9p\u00e9t\u00e9e<\/li>\n<li>ItemTemplate : Mod\u00e8le pour les Items.<\/li>\n<li>IsGroupingEnabled = true pour permettre le regroupement<\/li>\n<\/ul>\n<p>Les 2 DataTemplates sont d\u00e9finis dans des styles :<\/p>\n<p>Voici un exemple simpliste<\/p>\n<pre class=\"lang:default decode:true\">&lt;DataTemplate x:Key=\"NotifyItemTemplate\" &gt;\n    &lt;Grid Margin=\"0\"&gt;\n        &lt;Grid.ColumnDefinitions&gt;\n            &lt;ColumnDefinition \/&gt;\n            &lt;ColumnDefinition \/&gt;\n        &lt;\/Grid.ColumnDefinitions&gt;\n        &lt;TextBlock Margin=\"8 0 0 0\" Text=\"{Binding Title}\" Style=\"{ThemeResource BodyTextBlockStyle}\"\/&gt;\n        &lt;TextBlock Margin=\"8 0 0 0\" Grid.Column=\"1\" Text=\"{Binding FullDate}\" Style=\"{ThemeResource BodyTextBlockStyle}\"\/&gt;\n    &lt;\/Grid&gt;\n&lt;\/DataTemplate&gt;\n\n&lt;DataTemplate x:Key=\"MessageGroupHeader\"&gt;\n    &lt;Grid&gt;\n        &lt;Grid.RowDefinitions&gt;\n            &lt;RowDefinition\/&gt;\n            &lt;RowDefinition\/&gt;\n        &lt;\/Grid.RowDefinitions&gt;\n        &lt;TextBlock Text=\"{Binding Key}\" Style=\"{ThemeResource SubheaderTextBlockStyle}\"\/&gt;\n        &lt;Border Grid.Row=\"1\" Height=\"2\" Margin=\"0,0,0,0\" \n                HorizontalAlignment=\"Stretch\" \n                VerticalAlignment=\"Bottom\"\n                Background=\"Red\"\/&gt;\n    &lt;\/Grid&gt;                \n&lt;\/DataTemplate&gt;<\/pre>\n<p>Remarquez que l&rsquo;affichage du regroupement se fait par un {Binding Key}. Dans le cas ou le regroupement repr\u00e9sente un objet plus complexe (une image avec un titre par exemple), il faudrait Binder avec Key.NomDeLaPropri\u00e9t\u00e9 (Key.Image ou Key.Title par exemple).<\/p>\n<h1>Utilisation en WP8.1 XAML\u00a0(ou Windows 8.x)<\/h1>\n<p>La premi\u00e8re \u00e9tape est la d\u00e9finition d&rsquo;une nouvelle source de donn\u00e9es \u00ab\u00a0group\u00e9es\u00a0\u00bb.<\/p>\n<p>Pour cela, il faut d\u00e9finir une CollectionViewSource (dans les ressources de la page par exemple). La propri\u00e9t\u00e9 IsSourceGrouped=True est tr\u00e8s importante.<\/p>\n<pre class=\"lang:default decode:true \">CollectionViewSource \n                x:Name=\"ViewSourceMessagesByGroup\" \n                IsSourceGrouped=\"True\"\n                Source=\"{Binding MessagesByGroup}\"\/&gt;<\/pre>\n<p>Ensuite, il faut \u00ab\u00a0Binder\u00a0\u00bb cette propri\u00e9t\u00e9 de type staticRessource dans la ListView.<\/p>\n<pre class=\"lang:default decode:true\">{Binding Source={StaticResource ViewSourceMessagesByGroup} }<\/pre>\n<p><span style=\"color: #ff0000\">Tr\u00e8s important, le contr\u00f4le XAML utilis\u00e9 doit \u00eatre obligatoirement un ListView ou un GridView.<br \/>\n<\/span>La ListBox ne fonctionne pas pour un regroupement.<\/p>\n<p>La propri\u00e9t\u00e9 GroupStyle va ensuite permettre le regroupement de cette nouvelle source de donn\u00e9es.<\/p>\n<pre class=\"lang:default decode:true \">&lt;ListView\n        ItemsSource=\"{Binding Source={StaticResource ViewSourceMessagesByGroup} }\"    \n        ItemTemplate=\"{StaticResource NotifyItemTemplate}\" &gt;\n    &lt;ListView.GroupStyle&gt;\n        &lt;GroupStyle \n                HidesIfEmpty=\"True\" \n                HeaderTemplate=\"{StaticResource MessageGroupHeader}\"&gt;\n        &lt;\/GroupStyle&gt;\n    &lt;\/ListView.GroupStyle&gt;\n&lt;\/ListView&gt;\n<\/pre>\n<p>GroupStyle permet de d\u00e9finir l&rsquo;affichage du groupe HeaderTemplate.\u00a0Le style du\u00a0DataTemplate d\u00e9fini par HeaderTemplate\u00a0est 100% identique au template d\u00e9j\u00e0 utils\u00e9 dans votre ancien LongListSelector.<\/p>\n<p>Nous avons maintenant une liste avec une regroupement.<\/p>\n<p>HideIfEmpty correspond \u00e0 l&rsquo;ancienne propri\u00e9t\u00e9 HideEmptyGroups et permet d&rsquo;afficher ou cacher les groupes qui\u00a0contiennent aucun \u00e9l\u00e9ment.<\/p>\n<p>Le code source de l&rsquo;exemple se trouve ici :<\/p>\n<p><a title=\"Exemple migration LongListSelector en Universal Apps\" href=\"http:\/\/1drv.ms\/1qRVfWc\"><img decoding=\"async\" loading=\"lazy\" class=\"alignnone  wp-image-633\" src=\"http:\/\/dev.bratched.fr\/fr\/wp-content\/uploads\/sites\/2\/2014\/05\/download-10-icon-256.png\" alt=\"download-10-icon-256\" width=\"70\" height=\"70\" srcset=\"https:\/\/bratched.com\/fr\/wp-content\/uploads\/sites\/2\/2014\/05\/download-10-icon-256.png 256w, https:\/\/bratched.com\/fr\/wp-content\/uploads\/sites\/2\/2014\/05\/download-10-icon-256-150x150.png 150w\" sizes=\"(max-width: 70px) 100vw, 70px\" \/><\/a><\/p>\n<p>Pour le moment les groupes existent mais lorsque l&rsquo;on clique sur un groupe, rien ne se passe.<\/p>\n<p>Nous allons voir dans le prochain article comment cr\u00e9er la Jumplist permettant l&rsquo;affichage condens\u00e9 de tous les groupes.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Apr\u00e8s les ressources destin\u00e9es aux\u00a0traductions, nous continuons le tour d&rsquo;horizon des \u00e9l\u00e9ments n\u00e9cessaires\u00a0pour migrer d&rsquo;un projet Windows Phone 8.0 en Universal apps. Le LongListSelector est un \u00e9l\u00e9ment de liste tr\u00e8s souvent utilis\u00e9 : Il est apparu en 8.0 mais existait d\u00e9j\u00e0 dans la version 7.0 sous forme d&rsquo;un composant tiers du Windows Phone Toolkit. Avec [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[59,62,63],"tags":[101,3,102,4,58],"aioseo_notices":[],"_links":{"self":[{"href":"https:\/\/bratched.com\/fr\/wp-json\/wp\/v2\/posts\/732"}],"collection":[{"href":"https:\/\/bratched.com\/fr\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/bratched.com\/fr\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/bratched.com\/fr\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/bratched.com\/fr\/wp-json\/wp\/v2\/comments?post=732"}],"version-history":[{"count":0,"href":"https:\/\/bratched.com\/fr\/wp-json\/wp\/v2\/posts\/732\/revisions"}],"wp:attachment":[{"href":"https:\/\/bratched.com\/fr\/wp-json\/wp\/v2\/media?parent=732"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/bratched.com\/fr\/wp-json\/wp\/v2\/categories?post=732"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/bratched.com\/fr\/wp-json\/wp\/v2\/tags?post=732"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}