Creating Pushpin floating menu in Windows Phone application using Panorama and MessagePrompt

In this post I will create a some kind of details menu on bing map Pushpin using Panorama control and MessagePrompt from Coding4Fun Tools. That’s how result would be looks like:

First of all you need to download (from here) and add reference to Coding4Fun Tools in your project. I will use MessagePrompt, example of using it you can look here.

So let’s write some code.

In your xaml code define maps namespace:

xmlns:maps="clr-namespace:Microsoft.Phone.Controls.Maps;assembly=Microsoft.Phone.Controls.Maps"

Define pushpins collection within your bing map tags:

<maps:MapItemsControl ItemsSource="{Binding}">
            <maps:MapItemsControl.ItemTemplate>
                <DataTemplate>
                    <maps:Pushpin Location="{Binding Key}" Opacity="0.5" Background="Black" MouseLeftButtonUp="ContentPushpin_MouseLeftButtonUp"/>
                </DataTemplate>
            </maps:MapItemsControl.ItemTemplate>
        </maps:MapItemsControl>

ItemsSource we will bind to data context. And by the pushpin click we will call the ContentPushpin_MouseLeftButtonUp method. By clicking mouse right button and «Navigate to event handler» walk to code behind file and add the code below to ContentPushpin_MouseLeftButtonUp:

private void ContentPushpin_MouseLeftButtonUp(object sender, MouseButtonEventArgs e)
        {
            try
            {
                // Get clicked pushpin.
                clickedPushpin = sender as Pushpin;
                // Get it color.
                clickedPushpinColor = clickedPushpin.Background;
                // Change it's color to see it been clicked if we need some time to load content.
                clickedPushpin.Background = new SolidColorBrush(Color.FromArgb(255, 255, 0, 0));

                // Create panorama with for media content.
                Panorama mediaPanoramaControl = new Panorama();
                mediaPanoramaControl.Height = 500;

                // Get all images in this location.
                List<Image> allLocationImages = AllLocationsWithContent.Where(kvp => (kvp.Key == clickedPushpin.Location)).First().Value;

                // Insert all images in panorama items.
                foreach (Image content in allLocationImages)
                {
                    // New PanoramaItem for image.
                    PanoramaItem currentPanoramaItem = new PanoramaItem();
                    currentPanoramaItem.Content = content;

                    // Add current PanoramaItem to Panorama.
                    mediaPanoramaControl.Items.Add(currentPanoramaItem);
                }

                // Grid for mediaPanoramaControl.
                Grid grid = new Grid();
                grid.Children.Add(mediaPanoramaControl);

                // New floating message with pushpin details.
                mediaContentPanorama = new MessagePrompt
                {
                    Title = "Images in this location",
                    Body = grid,
                };

                // Add reaction to our floating details close.
                mediaContentPanorama.Completed += CloseMediaContentPamorama;
                mediaContentPanorama.Show();

            }
            catch (Exception exception)
            {
                // Using of another Coding4Fun control.
                AboutPrompt messageToUser = new AboutPrompt();
                messageToUser.Title = "Error!";
                messageToUser.Body = new TextBlock
                {
                    Text = exception.Message
                };
                messageToUser.Show();
            }
        }

What happens in this section of code you can get by reading my comments. We just get which of pushpins been clicked, by it location find all content (images) in corresponding ObservableCollection and fill them the new panorama element, which we place at new MessagePrompt. And after MessagePrompt would be closed we need change back pushpins color (mediaContentPanorama.Completed event):

        private void CloseMediaContentPamorama(object sender, PopUpEventArgs<string, PopUpResult> args)
        {
            // Change back clicked pushpin color.
            clickedPushpin.Background = clickedPushpinColor;
        }

Used in ContentPushpin_MouseLeftButtonUp code page class members defined below. Also here I fill collection of locations and images for pushpins binding in constructor:

        /// <summary>
        /// Clicked pushpin.
        /// </summary>
        private Pushpin clickedPushpin;

        /// <summary>
        /// Clicked pushpin color.
        /// </summary>
        private Brush clickedPushpinColor;

        /// <summary>
        /// Floating pushpins details.
        /// </summary>
        private MessagePrompt mediaContentPanorama;

        /// <summary>
        /// Dictionary of all locations with content.
        /// </summary>
        private ObservableCollection<KeyValuePair<GeoCoordinate, List<Image>>> AllLocationsWithContent;

        // Constructor
        public MainPage()
        {
            InitializeComponent();

            AllLocationsWithContent = new ObservableCollection<KeyValuePair<GeoCoordinate, List<Image>>>();
            this.DataContext = AllLocationsWithContent;

            // Downloading images and creating array for binding.

            Image currentImage = new Image();
            currentImage.Source = new BitmapImage(new Uri("Media/WP_000137.jpg", UriKind.Relative));

            List<Image> currentImageList = new List<Image>();
            currentImageList.Add(currentImage);

            currentImage = new Image();
            currentImage.Source = new BitmapImage(new Uri("Media/WP_000138.jpg", UriKind.Relative));

            currentImageList.Add(currentImage);

            currentImage = new Image();
            currentImage.Source = new BitmapImage(new Uri("Media/WP_000139.jpg", UriKind.Relative));

            currentImageList.Add(currentImage);

            // Array for binding. Now only with one element. Add pushpins to some location.
            AllLocationsWithContent.Add(new KeyValuePair<GeoCoordinate, List<Image>>(new GeoCoordinate(55.75f, 37.61f), currentImageList));

            currentImage = new Image();
            currentImage.Source = new BitmapImage(new Uri("Media/WP_000020.jpg", UriKind.Relative));

            currentImageList = new List<Image>();

            currentImageList.Add(currentImage);

            AllLocationsWithContent.Add(new KeyValuePair<GeoCoordinate, List<Image>>(new GeoCoordinate(56.00f, 38.00f), currentImageList));
        }

In general that’s all. After starting your project you will see two pushpins, and by clicking them you will see floating menu with images:

Two pushpinsYou can expand this menu by adding some element in panorama item. For example StackPanel with Checkboxes to choose images to delete. Or add buttons to MessagePrompt.

Source code you can get here.

Leonid.

Реклама