Warning : This page has been marked as an archive because the author consider that its content is no longer relevant.

J’ai récemment eu besoin de binder une collection de points sur le contrôle de carte du Windows Phone Toolkit. Je me suis alors trouvé face à un soucis auquel d’autres que moi se sont déjà attelés je pense notamment à Rudy Huyn ou il explique sa solution dans ce billet de blog : http://www.rudyhuyn.com/blog/2013/03/19/wp8-binder-une-collection-sur-une-map-2-le-retour/

Seulement dans mon cas cela ne suffisait pas car ma collection de points est parfois modifiée et le binding doit donc être refait. J’ai été confronté à deux exceptions différentes lorsque des modifications survenaient :

  • Items must be empty before using Items Source
  • Collection is in non writeable mode
collectiononwriteablemode.png itemssourcemustbeempty.png
Map controls

Afin de vous épargner pas mal de recherches et de tests voici la solution que j’ai mise en place et qui permet de ne plus être confronté à ces erreurs. Je précise que cette solution fonctionne dans mon cas mais n’est peut-être pas adaptée au votre. Pour commencer je suis parti du code du billet ci-dessus et j’ai ensuite modifié la méthode MapsItemsSourceChanged.

public class MapTools : DependencyObject
{
    [SuppressMessage("Microsoft.Design", "CA1062:Validate arguments of public methods", MessageId = "0", Justification = "Standard pattern.")]
    public static bool GetMapItemsSource(DependencyObject source)
    {
        return (bool)source.GetValue(MapItemsSourceProperty);
    }

    [SuppressMessage("Microsoft.Design", "CA1062:Validate arguments of public methods", MessageId = "0", Justification = "Standard pattern.")]
    public static void SetMapItemsSource(DependencyObject source, IEnumerable value)
    {
        source.SetValue(MapItemsSourceProperty, value);
    }

    public static readonly DependencyProperty MapItemsSourceProperty =
        DependencyProperty.Register("MapItemsSource", typeof(IEnumerable), typeof(Map), new PropertyMetadata(null, MapItemsSourceChanged));

    private static void MapItemsSourceChanged(DependencyObject sender, DependencyPropertyChangedEventArgs e)
    {
        var map = ((Map)sender);
        var itemsControl = MapExtensions.GetChildren(map).OfType<MapItemsControl>().FirstOrDefault();
        if (itemsControl == null)
            return;

        var list = itemsControl.ItemsSource as IList;
        var newList = e.NewValue as IEnumerable;
        if (list != null && list.IsReadOnly == false)
        {
            list.Clear();
            if (newList == null) return;
            foreach (var elem in newList)
                list.Add(elem);
        }
        else
        {
            itemsControl.ItemsSource = newList;
        }
    }
}

L’utilisation de ce code se fait de la même manière que celle présentée sur le billet de Rudy n’hésitez donc pas à aller y jeter un œil. Merci à lui ;-)

Comments