Results 1 to 4 of 4

Thread: Bing Map WPF control in a Windows Form

  1. #1

    Thread Starter
    Super Moderator Shaggy Hiker's Avatar
    Join Date
    Aug 2002
    Location
    Idaho
    Posts
    38,988

    Bing Map WPF control in a Windows Form

    I wanted to do a bit of work with maps. Microsoft has provided a nice WPF object for working with Bing Maps using the Bing Maps WPF Control found here:

    http://msdn.microsoft.com/en-us/library/hh750210.aspx

    I'm not really interested in using WPF, though, so I decided to wrap it into a Windows Form. I ended up putting the whole thing in a dll. The source for the dll is found here. There are two radiobuttons on the form for toggling between aerial (I only included aerial with annotations) and road views. The source for the form is here:

    The .designer.vb file contents for the form.
    Code:
    <Global.Microsoft.VisualBasic.CompilerServices.DesignerGenerated()> _
    Partial Class LocVisualizer
        Inherits System.Windows.Forms.Form
    
        'Form overrides dispose to clean up the component list.
        <System.Diagnostics.DebuggerNonUserCode()> _
        Protected Overrides Sub Dispose(ByVal disposing As Boolean)
            Try
                If disposing AndAlso components IsNot Nothing Then
                    components.Dispose()
                End If
            Finally
                MyBase.Dispose(disposing)
            End Try
        End Sub
    
        'Required by the Windows Form Designer
        Private components As System.ComponentModel.IContainer
    
        'NOTE: The following procedure is required by the Windows Form Designer
        'It can be modified using the Windows Form Designer.  
        'Do not modify it using the code editor.
        <System.Diagnostics.DebuggerStepThrough()> _
        Private Sub InitializeComponent()
            Me.rbAerial = New System.Windows.Forms.RadioButton()
            Me.rbRoad = New System.Windows.Forms.RadioButton()
            Me.SuspendLayout()
            '
            'rbAerial
            '
            Me.rbAerial.AutoSize = True
            Me.rbAerial.Location = New System.Drawing.Point(176, 8)
            Me.rbAerial.Name = "rbAerial"
            Me.rbAerial.Size = New System.Drawing.Size(77, 17)
            Me.rbAerial.TabIndex = 0
            Me.rbAerial.TabStop = True
            Me.rbAerial.Text = "Aerial View"
            Me.rbAerial.UseVisualStyleBackColor = True
            '
            'rbRoad
            '
            Me.rbRoad.AutoSize = True
            Me.rbRoad.Location = New System.Drawing.Point(296, 8)
            Me.rbRoad.Name = "rbRoad"
            Me.rbRoad.Size = New System.Drawing.Size(74, 17)
            Me.rbRoad.TabIndex = 1
            Me.rbRoad.TabStop = True
            Me.rbRoad.Text = "RoadView"
            Me.rbRoad.UseVisualStyleBackColor = True
            '
            'LocVisualizer
            '
            Me.AutoScaleDimensions = New System.Drawing.SizeF(6.0!, 13.0!)
            Me.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font
            Me.ClientSize = New System.Drawing.Size(761, 506)
            Me.Controls.Add(Me.rbRoad)
            Me.Controls.Add(Me.rbAerial)
            Me.Name = "LocVisualizer"
            Me.Text = "LocVisualizer"
            Me.ResumeLayout(False)
            Me.PerformLayout()
    
        End Sub
        Friend WithEvents rbAerial As System.Windows.Forms.RadioButton
        Friend WithEvents rbRoad As System.Windows.Forms.RadioButton
    End Class
    The code for the form:
    Code:
    Public Class LocVisualizer
    
        Private nCtrl As ImageHost
        Private mNotNow As Boolean
    
        Public Sub New(latitude As Double, longitude As Double, zoomLevel As Integer, viewType As DisplayMode, displayName As String)
            mNotNow = True
            ' This call is required by the designer.
            InitializeComponent()
    
            If displayName Is Nothing OrElse displayName = String.Empty Then
                Me.Text = "Location Visualizer"
            Else
                Me.Text = displayName
            End If
    
            'If viewType = DisplayMode.Aerial Then
            '    Me.rbAerial.Checked = True
            'Else
            '    Me.rbRoad.Checked = True
            'End If
    
            nCtrl = New ImageHost
            nCtrl.Top = 56
            nCtrl.Left = 0
            nCtrl.Width = Me.Width
            nCtrl.Height = Me.Height
            nCtrl.Anchor = CType((Windows.Forms.AnchorStyles.Bottom Or Windows.Forms.AnchorStyles.Left Or Windows.Forms.AnchorStyles.Right Or Windows.Forms.AnchorStyles.Top), Windows.Forms.AnchorStyles)
    
            Me.Controls.Add(nCtrl)
            nCtrl.ShowLocation(latitude, longitude, zoomLevel, viewType)
            mNotNow = False
        End Sub
    
        Public Property ZoomLevel As Double
            Get
                Return nCtrl.ZoomLevel
            End Get
            Set(value As Double)
                nCtrl.ZoomLevel = value
            End Set
        End Property
    
        Public Function AddPin(latitude As Double, longitude As Double) As Integer
            Return nCtrl.AddPushpin(latitude, longitude)
        End Function
    
        Public Sub RemovePin(index As Integer)
            nCtrl.RemovePushpin(index)
        End Sub
    
        Private Sub LocVisualizer_Shown(sender As Object, e As System.EventArgs) Handles Me.Shown
            nCtrl.Focus()
        End Sub
    
        Private Sub rbAerial_CheckedChanged(sender As System.Object, e As System.EventArgs) Handles rbAerial.CheckedChanged
            If Me.rbAerial.Checked AndAlso mNotNow = False Then
                nCtrl.ViewMode = DisplayMode.Aerial
                nCtrl.Focus()
            End If
        End Sub
    
        Private Sub rbRoad_CheckedChanged(sender As System.Object, e As System.EventArgs) Handles rbRoad.CheckedChanged
            If Me.rbRoad.Checked AndAlso mNotNow = False Then
                nCtrl.ViewMode = DisplayMode.Road
                nCtrl.Focus()
            End If
        End Sub
    End Class
    And finally, the code for the hosting control:
    Code:
    Imports System.Windows.Controls
    Imports System.Windows.Media.Imaging
    
    Friend Class ImageHost
        Inherits System.Windows.Forms.Integration.ElementHost
    
        'Private mImage As New System.Windows.Controls.Image
        Private mMapControl As New Microsoft.Maps.MapControl.WPF.Map
    
        Private mAllGood As Boolean
    
        Friend ReadOnly Property AllIsWell As Boolean
            Get
                Return mAllGood
            End Get
        End Property
    
        Friend Sub New()
            MyBase.Child = mMapControl
        End Sub
    
        Friend Sub ShowLocation(latitude As Double, longitude As Double, zoomLevel As Integer, displayType As DisplayMode)
            mMapControl.CredentialsProvider = New Microsoft.Maps.MapControl.WPF.ApplicationIdCredentialsProvider(<your api key here>)
            If displayType = 0 Then
                mMapControl.Mode = New Microsoft.Maps.MapControl.WPF.AerialMode(True)
            Else
                mMapControl.Mode = New Microsoft.Maps.MapControl.WPF.RoadMode
            End If
            mMapControl.ZoomLevel = zoomLevel
            mMapControl.Center = New Microsoft.Maps.MapControl.WPF.Location(latitude, longitude)
            Dim pin As New Microsoft.Maps.MapControl.WPF.Pushpin()
            pin.Location = mMapControl.Center
            mMapControl.Children.Add(pin)
        End Sub
               
        Friend Property ZoomLevel As Double
            Get
                Return mMapControl.ZoomLevel
            End Get
            Set(value As Double)
                mMapControl.ZoomLevel = value
            End Set
        End Property
    
        Friend Function AddPushpin(latitude As Double, longitude As Double) As Integer
            Dim pin As New Microsoft.Maps.MapControl.WPF.Pushpin()
            pin.Location = New Microsoft.Maps.MapControl.WPF.Location(latitude, longitude)
    
            Return mMapControl.Children.Add(pin)
        End Function
    
        Friend Sub RemovePushpin(index As Integer)
            mMapControl.Children.RemoveAt(index)
        End Sub
    
        Friend Property ViewMode As DisplayMode
            Get
                If mMapControl.Mode.Name.StartsWith("R") Then 'Hoo boy, is THIS a hack solution!
                    Return DisplayMode.Road
                Else
                    Return DisplayMode.Aerial
                End If
            End Get
            Set(value As DisplayMode)
                Select Case value
                    Case DisplayMode.Aerial
                        mMapControl.Mode = New Microsoft.Maps.MapControl.WPF.AerialMode(True)
                    Case DisplayMode.Road
                        mMapControl.Mode = New Microsoft.Maps.MapControl.WPF.RoadMode
                End Select
            End Set
        End Property
    
    End Class
    
    
    Public Enum DisplayMode
        Road
        Aerial
    End Enum
    My usual boring signature: Nothing

  2. #2

    Thread Starter
    Super Moderator Shaggy Hiker's Avatar
    Join Date
    Aug 2002
    Location
    Idaho
    Posts
    38,988

    Re: Bing Map WPF control in a Windows Form

    To use this, download and install the Bing Map WPF Control from the link provided. Also on the link provided is a discussion about getting a Bing Maps API key, which you will need to supply at the point noted <your api key here> in the code.

    With that code, the maps toggle between road and aerial, and the user can scroll around the map as well as zooming in and zooming out. I added a property to allow you to set the zoom level, as well as setting an initial zoom level, but I don't find that to be particularly useful. Since the control already offers the ability to zoom around, all that you are doing by setting a zoom level is setting a starting vantage point, at best. I found that an initial zoom level of 15 was pretty reasonable for what I was doing.
    My usual boring signature: Nothing

  3. #3
    Frenzied Member
    Join Date
    Jul 2006
    Location
    MI
    Posts
    1,965

    Re: Bing Map WPF control in a Windows Form

    Shaggy ... I've been researching how to add the Bing Maps WPF control to a windows form project & ran across your post here. I downloaded & referenced the Bing DLL & tried your code. I'm getting hung up on the ImageHost. ("Private nCtrl As ImageHost") I don't know what it is or how to declare it. Do I just paste your code into a class called "ImageHost"? Can you clarify? Do I need to add any other references besides the Bing DLL? Also, would it be possible for you to attach the project for downloading? Thanks...
    Last edited by nbrege; Feb 24th, 2016 at 01:54 PM.

  4. #4

    Thread Starter
    Super Moderator Shaggy Hiker's Avatar
    Join Date
    Aug 2002
    Location
    Idaho
    Posts
    38,988

    Re: Bing Map WPF control in a Windows Form

    ImageHost is the third snippet shown in the first post. That is a class derived from ElementHost, for which you will need a reference to
    WindowsFormsIntegration. You may also need a reference to WindowsBase, since I have one, but WindowsFormsIntegration is where you will find ElementHost, which is the base class for ImageHost.
    My usual boring signature: Nothing

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  



Click Here to Expand Forum to Full Width