Click or drag to resize
Code Example - BingLayer_Advanced

Teaches one method (advanced) for using the Microsoft WebClient and a DataContract to poll a Microsoft Bing development server to determine if a Bing Key is correct and then loading multiple BingLayer's into the Map and allowing the user to switch between various BingLayer.MapStyles.

Code Example
Bing Layer Advanced

This section contains selected code files from a Visual Studio project that emphasize specific ArcGIS Runtime SDK (Windows Desktop) features. For example: some code examples may accomplish the bulk of the work as a configuration property in the .xaml file and hence only the .xaml file will be shown in detail below. In other code examples, the .xaml is used to define the configuration of graphical elements for the application but the application logic is performed in the code behind, hence you may see both the .xaml and .cs/.vb files shown in detail below.

XAML
<Window x:Class="BingLayer_Advanced.MainWindow"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:esri="http://schemas.esri.com/arcgis/runtime/2013"
    Title="MainWindow" Height="600" Width="800">
    <Grid>

        <!-- Add a MapView Control with an empty Map. -->
        <esri:MapView>
            <esri:Map x:Name="Map1" />
        </esri:MapView>

        <!--
        Add a set of controls to have the user supply a Bing Key 64+ character string. When the user believes they have supplied the correct Bing Key string
        the 'Load Map' button will enable so the user can click it to render various BingLayers in the map. If the user does not have a Bing Key, then they 
        can click the 'Get Bing Key' button to obtain one from Microsoft. This set of controls is visible when the application is first loaded and then goes
        away when user enters the correct Bing Key. 
        -->
        <Border Name="BingKeyGrid" BorderBrush="Black" BorderThickness="1" Background="White" HorizontalAlignment="Right" VerticalAlignment="Top" Margin="10">
            <StackPanel Orientation="Vertical" HorizontalAlignment="Center" Margin="10">
                <StackPanel Orientation="Horizontal" HorizontalAlignment="Center" VerticalAlignment="Center" Margin="2" >
                    <TextBlock FontWeight="Bold" HorizontalAlignment="Center" VerticalAlignment="Center" Text="Enter Bing Key" Margin="2" Foreground="Black" />
                    <Button Margin="2" Content="Get Bing Key" Click="Button_Click"/>
                </StackPanel>
                <TextBox x:Name="BingKeyTextBox" Width="250" HorizontalAlignment="Right" Margin="0,2,0,2" TextChanged="BingKeyTextBox_TextChanged" />
                <TextBlock Name="InvalidBingKeyTextBlock" Text="Invalid Key" Foreground="Red" Margin="0,2,0,2" HorizontalAlignment="Center" Visibility="Collapsed"/>
                <Button Name="LoadMapButton" Content="Load Map" Width="100" Margin="0,5,0,10" IsEnabled="False" HorizontalAlignment="Center" Click="LoadMapButton_Click" />
            </StackPanel>
        </Border>


        <!-- 
        Add RadioButtons; one for each different MapStyle of BingLayer that is supported. The RadioButton.Tag property contains
        the string name of the BingLayer.MapStyle; this will be used in the code behind to turn on/off the visibility of the 
        various BingLayer's that are loaded. The same RadioButton.Click event is used to switch between the BingLayers. 
        NOTE: By default, these entire set of controls have their visibility set to collapsed and will not appear to the user
        unless the correct BingLayer.Key is supplied.
        -->
        <Border Name="LayerStyleGrid" BorderBrush="Black" BorderThickness="1" Background="White" HorizontalAlignment="Right" VerticalAlignment="Top" Margin="10" Visibility="Collapsed">
            <StackPanel Orientation="Horizontal" HorizontalAlignment="Center" Margin="5">
                <RadioButton x:Name="RoadRadioButton" Tag="Road" IsChecked="true" Margin="5,0,0,0" GroupName="Layers" Content="Road" Click="RadioButton_Click"/>
                <RadioButton x:Name="AerialRadioButton" Tag="Aerial" Margin="5,0,0,0" GroupName="Layers" Content="Aerial" Click="RadioButton_Click"/>
                <RadioButton x:Name="AerialWithLabelsRadioButton" Tag="AerialWithLabels" Margin="5,0,0,0" GroupName="Layers" Content="Aerial - Labels" Click="RadioButton_Click"/>
            </StackPanel>
        </Border>

    </Grid>
</Window>

SPECIAL NOTE: The XAML displayed above comes from a C# project. If you are a VB.NET developer, you will need to modify the text for the x:Class namespace from "BingLayer_Advanced.MainWindow" to be just "MainWindow".

// NOTE: You will need to add a Reference to the System.Runtime.Serialization.Json Assembly in your Visual Studio project.

namespace BingLayer_Advanced
{
    public partial class MainWindow : System.Windows.Window
    {
        public MainWindow()
        {
            InitializeComponent();
        }

        private void RadioButton_Click(object sender, System.Windows.RoutedEventArgs e)
        {
            // This function turns on/off the various BingLayer's loaded in the Map based upon user interactions with the RadioButtons.

            // Get the string version of the BingLayer.MapStyle from the RadioButton.Tag property.
            System.Windows.Controls.RadioButton myRadioButton = ((System.Windows.Controls.RadioButton)sender);
            string myLayerNameTag = System.Convert.ToString(myRadioButton.Tag);

            // Loop through the LayerCollection and turn off the visibility of all the BingLayers.
            foreach (Esri.ArcGISRuntime.Layers.Layer oneLayer in Map1.Layers)
            {
                if (oneLayer is Esri.ArcGISRuntime.Layers.BingLayer)
                {
                    oneLayer.IsVisible = false;
                }
            }

            // Turn on the visibility of the BingLayer that matches the RadioButton that was just clicked.
            Esri.ArcGISRuntime.Layers.LayerCollection myLayerCollection = Map1.Layers;
            Esri.ArcGISRuntime.Layers.BingLayer myBingLayer = (Esri.ArcGISRuntime.Layers.BingLayer)myLayerCollection[myLayerNameTag];
            myBingLayer.IsVisible = true;
        }

        private void BingKeyTextBox_TextChanged(object sender, System.Windows.Controls.TextChangedEventArgs e)
        {
            // This function enabled the 'Load Map' button when a 64+ character BingLayer.Key is entered.

            // Only enable the 'Load Map' button when the user enter Bing Key string is greater than 64 characters in length.
            System.Windows.Controls.TextBox myTextBox = (sender as System.Windows.Controls.TextBox);
            if ((myTextBox.Text.Length) >= 64)
            {
                LoadMapButton.IsEnabled = true;
            }
            else
            {
                LoadMapButton.IsEnabled = false;
            }
        }

        private void Button_Click(object sender, System.Windows.RoutedEventArgs e)
        {
            // Launch an Internet Explorer web browser and point the Url to the Microsoft Bing web site for the user to obtain a Bing Key.
            System.Diagnostics.Process.Start("IExplore.exe", "https://www.bingmapsportal.com");
        }

        private void LoadMapButton_Click(object sender, System.Windows.RoutedEventArgs e)
        {
            // This function occurs when the user clicks the 'Load Map' button. Using the standard Microsoft WebClient control, attempt to access the Bing Map's
            // developer web server to determine if the Bing Key entered is valid. A custom JSON DataContract is used to read the response from the Bing Map's 
            // development web server to determine if the 'ValidCredentials' JSON syntax is returned for the Bing Key provided by the user. If the Bing Key
            // credentials are valid, then all the BingLayer.MapStyle type of services are loaded into the Map's LayerCollection, as well as hiding the controls 
            // to force the user to enter the Bing Key. 

            // Create a new instance of the Microsoft WebClient control. 
            System.Net.WebClient myWebClient = new System.Net.WebClient();

            // Construct a Url with the Bing Key as a argument pair to contact the Microsoft development Bing web server. 
            string myUri = string.Format("http://dev.virtualearth.net/REST/v1/Imagery/Metadata/Aerial?supressStatus=true&key={0}", BingKeyTextBox.Text);

            // Wire up an Event Handler on the WebClient Control to execute when web request is completed.
            myWebClient.OpenReadCompleted += (s, a) =>
            {
                if (a.Error == null)
                {
                    // There was no error returned from the WebClient.OpenReadCompleted call.

                    // Create a new DataContractJsonSerializer using our custom BingAuthentication DataContract defined at the end of this class file. 
                    System.Runtime.Serialization.Json.DataContractJsonSerializer mySerializer = new System.Runtime.Serialization.Json.DataContractJsonSerializer(typeof(BingAuthentication));

                    // Set the result of the DataContractJsonSerializer.ReadObject to our custom BigAuthentication DataContract.
                    BingAuthentication myBingAuthentication = mySerializer.ReadObject(a.Result) as BingAuthentication;

                    // Close the IOStream of the WebClient.DownloadDataAsync method call.
                    a.Result.Close();

                    // Get the BingAuthentication.AuthenticationResultCode string from the DataContract.
                    string myAuthenticationResult = myBingAuthentication.AuthenticationResultCode.ToString();

                    // Test if the BingAuthentication.AuthenticationResultCode equals the string 'ValidCredentials'
                    if (myAuthenticationResult == "ValidCredentials")
                    {
                        // We did get back the string 'ValidCredentials' from the WebClient request to the development Microsoft Bing web site.

                        // Get the Enumerations of BingLayer.MapStyle types of Bing maps that are available from Microsoft.
                        System.Array myBingLayerTypes = System.Enum.GetValues(typeof(Esri.ArcGISRuntime.Layers.BingLayer.LayerType));
                        int[] myLayerTypes = (int[])myBingLayerTypes;

                        // Loop through each BingLayer.MapStyle enumeration value (an Integer). 
                        foreach (Esri.ArcGISRuntime.Layers.BingLayer.LayerType myLayerType in myLayerTypes)
                        {
                            // Create a new BingLayer and set the various properties (.ID, .MapStyle, .Key, and .IsVisible)
                            Esri.ArcGISRuntime.Layers.BingLayer myBingLayer = new Esri.ArcGISRuntime.Layers.BingLayer();
                            myBingLayer.ID = myLayerType.ToString();
                            myBingLayer.MapStyle = myLayerType;
                            myBingLayer.Key = BingKeyTextBox.Text;
                            myBingLayer.IsVisible = false;

                            // Add each of the different Bing maps types to the Map's LayerCollection.
                            Map1.Layers.Add(myBingLayer);
                        }

                        // Make the first BingLayer in the BingLayer() array be the one that is visible to the user.
                        Map1.Layers[0].IsVisible = true;

                        // Hide the controls that the user has to enter the Bing Key.
                        BingKeyGrid.Visibility = System.Windows.Visibility.Collapsed;
                        InvalidBingKeyTextBlock.Visibility = System.Windows.Visibility.Collapsed;

                        // Show the RadioButton controls that allow the user to switch between viewing the different BingLayer types.
                        LayerStyleGrid.Visibility = System.Windows.Visibility.Visible;
                    }
                    else
                    {
                        // We did NOT get back the string 'ValidCredentials' from the WebClient request to the development Microsoft Bing web site.
                        // Keep the set of controls prompting the user for a valid Bing Key.

                        InvalidBingKeyTextBlock.Visibility = System.Windows.Visibility.Visible;
                    }
                }
                else
                {
                    // There WAS an error returned from the WebClient.OpenReadCompleted call. 
                    // Keep the set of controls prompting the user for a valid Bing Key.

                    InvalidBingKeyTextBlock.Visibility = System.Windows.Visibility.Visible;
                }
            };

            // Call the WebClient.OpenReadAsync Method using the Uri constructed above. This will cause the above in-line WebClient.OpenReadCompleted Event fire. 
            myWebClient.OpenReadAsync(new System.Uri(myUri));
        }

        // Create a custom BingAuthentication class that can be used to hold JSON serializable information from the WebClient. We will use this to see if
        // we get back the string 'ValidCredentials' from a Microsoft Bing development web server for a specific Bing Key provided by the user.
        [System.Runtime.Serialization.DataContract]
        public class BingAuthentication
        {
            [System.Runtime.Serialization.DataMember(Name = "authenticationResultCode")]
            public string AuthenticationResultCode { get; set; }
        }
    }
}