-
Dec 16th, 2014, 06:45 PM
#1
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
-
Dec 16th, 2014, 06:51 PM
#2
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
-
Feb 24th, 2016, 01:30 PM
#3
Frenzied Member
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.
-
Feb 24th, 2016, 05:34 PM
#4
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
-
Forum Rules
|
Click Here to Expand Forum to Full Width
|