IronPython Windows Forms Tutorial
From Empty Window to MapPoint Client
Contributor: Martin Schray
Information in this document is subject to change without notice. The example companies, organizations, products, people, and events depicted herein are fictitious. No association with any real company, organization, product, person or event is intended or should be inferred. Complying with all applicable copyright laws is the responsibility of the user. Without limiting the rights under copyright, no part of this document may be reproduced, stored in or introduced into a retrieval system, or transmitted in any form or by any means (electronic, mechanical, photocopying, recording, or otherwise), or for any purpose, without the express written permission of Microsoft Corporation.
Microsoft may have patents, patent applications, trademarked, copyrights, or other intellectual property rights covering subject matter in this document. Except as expressly provided in any written license agreement from Microsoft, the furnishing of this document does not give you any license to these patents, trademarks, copyrights, or other intellectual property.
© Microsoft Corporation. All rights reserved.
Microsoft, MS-DOS, MS, Windows, Windows NT, MSDN, Active Directory, BizTalk, SQL Server, SharePoint, Outlook, PowerPoint, FrontPage, Visual Basic, Visual C++, Visual J++, Visual InterDev, Visual SourceSafe, Visual C#, Visual J#, and Visual Studio are either registered trademarks or trademarks of Microsoft Corporation in the U.S.A. and/or other countries.
Other product and company names herein may be the trademarks of their respective owners.
This source code is subject to terms and conditions of the Apache License, Version 2.0. A copy of the license can be found in the License.html file at the root of this distribution. If you cannot locate the Apache License, Version 2.0, please send an email to ironpy@microsoft.com. By using this source code in any fashion, you are agreeing to be bound by the terms of the Apache License, Version 2.0.
Prerequisites
The prerequisites to successfully run this application are:
Contents
Tutorial 1: Building Windows Forms applications
Exercise 1: Building Interesting Windows Forms Applications
Task 1: Create an Empty Windows Forms Application
Task 2: Add Controls to a Windows Forms Application
Task 3: Add Controls that Work Together
Task 4: Add Non-visible Components to the Form
Task 5: Use Layout Panels to Automatically Layout Controls
Task 6: Add a Web Browser to the Form
Task 7: Displaying a Map Picture with Data from MapPoint
Task 8: Add Route-finding to the Map Application
In this tutorial we interactively build a Windows Form. We will look at eight Windows Forms Applications that progress from a Windows Form window with just a title to an application that uses the MapPoint web service. We will discuss the Windows Forms code so that you understand within each task what the IronPython code is doing. However, though the applications are relatively small, there's enough code that you won't want to type it into the IronPython console. Each task will simply direct you to run the application from a Windows cmd.exe window, as you would launch any Python script.
Estimated time to complete this tutorial: 40 minutes
The objective of this tutorial is to familiarize you with more Windows Forms features using IronPython.
The goal of this exercise is to provide some simple examples of IronPython Windows Forms applications. The first few tasks will be quite simple and lack any real sophistication, but provide the building blocks for building more complete UI as you progress through the tasks. Some of the tasks build on the code from previous tasks, but each task provides full source code and is meant to run as a complete example.
The tasks that use MapPoint Web Services require the MapPointWebServicesProject.dll. Task 7 contains an extra step that tells you how to build this DLL.
Task 1 creates an empty Windows form and sets the window title of the form. The first three lines of code are the required imports. We need to add a reference to System.Windows.Forms, and then we can import all the names from it into our module.
The class FormV1 inherits from System.Windows.Forms.Form, so that it has all the default behaviors of a form. The __init__ method is used to set the forms window title. Finally, we invoke Application.Run to launch our form into action.
import clr
clr.AddReference("System.Windows.Forms")
from System.Windows.Forms import *
class FormV1(Form):
def __init__(self):
self.Text = 'Hello World'
Application.Run(FormV1())
1. Now let's try the Windows Form application by launching the IronPython script from a cmd.exe window:
ipyw.exe winforms\formV1.py
Note, we're using the ipyw.exe executable instead of the ipy.exe. Ipyw.exe launches the Windows Forms application and returns control to the cmd.exe it was launched from since the Windows Form application executes independently.
You should see the following window pop up on your screen:

Task 2 creates a Windows form, sets the window title of the form, adds our first control (a Button), and hooks up the Click of the button to display a MessageBox when the Button is clicked. We show the new lines of code highlighted below. As in the previous task, the first three lines of code are the required imports. We need to add a reference to System.Windows.Forms, and then we can import from it to bring all the names from that module into ours.
The class FormV2 inherits from System.Windows.Forms.Form, so that it has all the default behaviors of a form. The __init__ method is used set up instances of our form. First we set the Form's title (self.Text).
Now for the new code. We create a Button with the text 'Message', and we set its location. Third we hook the Button's Click event so that when the button is clicked the OnMsgButtonClick method is called. Then we add the Button to the form's list of controls.
Next we define OnMsgButtonClick, which takes two arguments. OnMsgButtonClick simply calls MessageBox.Show to show a classic message box pop up.
Lastly, we invoke Application.Run to launch our form into action.
import clr
clr.AddReference("System.Windows.Forms")
from System.Windows.Forms import *
class FormV2(Form):
def __init__(self):
self.Text = 'Hello World'
msgButton = Button(Text='Message', Left =20, Top=20)
msgButton.Click += self.OnMsgButtonClick
self.Controls.Add(msgButton)
def OnMsgButtonClick(self,
*args):
MessageBox.Show("Hello World")
Application.Run(FormV2())
1. Now let's try the Windows Form application by launching the IronPython script from a cmd.exe window:
ipyw.exe winforms\formV2.py
You should see the following window pop up on your screen:

When you click the Button, you will see the following window:

Task 3 creates a Windows form, sets the window title of the form, adds a Label, Textbox, and a Button. We hook up the Click of the button to display a MessageBox when the Button is clicked, but in this task we use the text from the Textbox. As in the previous tasks, the first three lines of code are the required imports. We need to add a reference to System.Windows.Forms, and then we can import from it to bring all the names from that module into ours.
The class FormV3 inherits from System.Windows.Forms.Form so that it has all the default behaviors of a form. The __init__ method is used to set up instances of our form. First we set the Form's title (self.Text).
Now for the new code (highlighted below). We create a Label and add it to the form's controls. Then we create a TextBox, and set its location before adding it to the form's controls. A reference (self.txtMessage) to the TextBox is kept so that in OnMsgButtonClick we can get the Text from the TextBox.
As before, we create a Button with the text 'Message'. We make it visible and set its location (which is slightly lower down in the form in this task). We hook the Button's Click event up so that when the button is clicked the OnMsgButtonClick method is called. Then we add the Button to the form's list of controls.
Next we define OnMsgButtonClick, which takes two arguments. OnMsgButtonClick simply calls MessageBox.Show to display the text in the TextBox in a classic message box pop up.
Lastly, we invoke Application.Run to launch our form.
import clr
clr.AddReference("System.Windows.Forms")
from System.Windows.Forms import *
class FormV3(Form):
def __init__(self):
self.Text = 'Hello World'
# Create Label
self.Controls.Add(Label(Text='Enter Message:'))
# Create TextBox
self.txtMessage = TextBox(Left=100)
self.Controls.Add(self.txtMessage)
# Create Button
msgButton = Button(Text='Message', Left =20, Top=25)
msgButton.Click += self.OnMsgButtonClick
self.Controls.Add(msgButton)
def OnMsgButtonClick(self,
*args):
MessageBox.Show(self.txtMessage.Text,"Message")
Application.Run(FormV3())
1. Now let's try the Windows Form application by launching the IronPython script from a cmd.exe window:
ipyw.exe winforms\formV3.py
You should see the following window pop up on your screen:

Task 4 has the same basic UI that task 3 had which was a form with a Label, TextBox, and a Button. The difference is that we begin to use non-visible components in task 4. Components allow us to add objects that don't necessarily have a visual representation. For example, a Timer is a component that doesn't appear visibly on the form. In task 4 we will use a NotifyIcon to allow our application to appear in the system tray and ContextMenuStrip to give NotifyIcon a right-click menu. Our first few lines of code now have a few additions since we need to access and import the System.Drawing namespace. We need the System.Drawing namespace to access the Icon class. The Icon class is used to associate an icon file with our NotifyIcon.
The good news is that the code to set the form's title, as well as create the Label, TextBox, and Button are the same as Task 3. Now let's get to the new code. Before we can add the Components to our form we must create the components container to hold them. Next we will create the ContextMenuStrip as well as the ContextMenuItem and add them (the ContextMenuStrip holds ContextMenuItems). Next we setup the ContextMenuItem's click event to call the OnExitClick method, which will close our application. Having setup the ContextMenuStrip and it's ContextMenuItem, we turn our attention to the NotifyIcon. We setup the NotifyIcon and associate the ContextMenuStrip with the NotifyIcon. The OnMsgButtonClick method displays the text in the TextBox just as in task 3. Next we define our OnExitClick method which closes the form to exit the application. This is followed by the definition of OnNotifyIconExit used to remove the notify icon after the application is closed. Lastly, we invoke Application.Run to launch our form into action.
import clr
clr.AddReference("System.Windows.Forms")
from System.Windows.Forms import *
clr.AddReference("System.Drawing")
from System.Drawing import *
import System
from System import *
class FormV4(Form):
def __init__(self):
self.Text = 'Hello World'
# Create Label
self.Controls.Add(Label(Text='Enter Message:'))
# Create TextBox
self.txtMessage = TextBox(Left=100)
self.Controls.Add(self.txtMessage)
# Create Button
msgButton = Button(Text='Message', Left =20, Top=25)
msgButton.Click += self.OnMsgButtonClick
self.Controls.Add(msgButton)
# Create Component Container
self._components = System.ComponentModel.Container()
#
# Add component - ContextMenu
#
self._contextMenuStrip1 = ContextMenuStrip(self._components)
self._exitToolStripMenuItem = ToolStripMenuItem(Text='Exit')
self._contextMenuStrip1.Items.Add(self._exitToolStripMenuItem)
self._exitToolStripMenuItem.Click += self.OnExitClick
#
# add Component - NotifyIcon
#
self._notifyIcon1 = NotifyIcon(self._components,Visible=True,Text='Test')
self._notifyIcon1.Icon = Icon("Winforms\\app.ico")
self._notifyIcon1.ContextMenuStrip = self._contextMenuStrip1
self.Closed += self.OnNotifyIconExit
def OnMsgButtonClick(self, *args):
MessageBox.Show(self.txtMessage.Text,"Message")
def OnExitClick(self, *args):
self.Close()
def OnNotifyIconExit(self, *args):
self._notifyIcon1.Dispose()
Application.Run(FormV4())
1. Now let's try the Windows Form application by launching the IronPython script from a cmd.exe window:
ipyw.exe winforms\formV4.py
You should see the following window pop up on your screen:

Additionally you should see the following icon in your system tray. If you place your mouse over the icon the text 'test' will appear. If you right click on the icon the context menu will appear. Selecting 'Exit' will cause the application to close.
Task 5 has the same basic UI that task 4 had which was a form with a Label, TextBox, and Button. Task 5 also includes the NotifyIcon, ContextMenuStrip, and ContextMenuItem components. The big change in task 5 is that we begin to use layout panels to make it easier to layout controls. For example, in task 4 we had to go through the effort of setting the location of the Label, TextBox, and Button. Typically it takes some trial and error to make sure the controls are placed correctly. Instead, we use a FlowLayoutPanel to automatically place the controls. As the name implies the controls are flowed as space allows.
The best way to illustrate this is an example. Notice that in the image on the left below that there is not enough room to display all the controls horizontally, so they are stacked to fit vertically. In the image on the right below there is enough space to horizontally place all the controls so the FlowLayout Panel does so. So the FlowLayoutPanel can actually reposition controls as the form resizes.
Other than the order in which the controls are created, the only different lines of code from the previous task are creating the FlowLayoutPanel and adding the controls to it. Also, we add the FlowLayoutPanel to the Form's controls.

import clr
clr.AddReference("System.Windows.Forms")
clr.AddReference("System.Drawing")
from System.Windows.Forms import *
from System.Drawing import *
import System
from System import *
class FormV5(Form):
def __init__(self):
self.Text = 'Hello World'
self.txtMessage = TextBox()
msgButton = Button(Text='Message')
msgButton.Click += self.OnmsgButtonClick
#
#
Create FlowPanelLayout and add controls
#
self._flowLayoutPanel1 = FlowLayoutPanel(Dock = DockStyle.Fill)
self._flowLayoutPanel1.Controls.Add(Label(Text='Enter Message:'))
self._flowLayoutPanel1.Controls.Add(self.txtMessage)
self._flowLayoutPanel1.Controls.Add(msgButton)
self.Controls.Add(self._flowLayoutPanel1)
self._components = System.ComponentModel.Container()
#
#
Add component - ContextMenu
#
self._contextMenuStrip1 = ContextMenuStrip(self._components)
self._exitToolStripMenuItem = ToolStripMenuItem(Text='Exit')
self._exitToolStripMenuItem.Click += self.OnExitClick
self._contextMenuStrip1.Items.Add(self._exitToolStripMenuItem)
#
#
add Component - NotifyIcon
#
self._notifyIcon1 =
NotifyIcon(self._components,Visible=True,Text='Test')
self._notifyIcon1.Icon = Icon("Winforms\\app.ico")
self._notifyIcon1.ContextMenuStrip = self._contextMenuStrip1
self.Closed += self.OnNotifyIconExit
def OnmsgButtonClick(self,
*args):
MessageBox.Show(self.txtMessage.Text,"Message")
def OnExitClick(self, *args):
self.Close()
def OnNotifyIconExit(self, *args):
self._notifyIcon1.Dispose()
Application.Run(FormV5())
1. Now let's try the Windows Form application by launching the IronPython script from a cmd.exe window:
ipyw.exe winforms\formV5.py
Task 6 takes our basic form with a Label, TextBox, and a Button, but now we add a WebBrowser control to make a very simple web browser. Continuing on the theme from task 5, we want to build an application with a sophisticated UI with little work to position controls.
We will introduce a TabelLayoutPanel that will allow the area of the application containing the Label, TextBox, and Button to stay roughly the same size while allowing the web browser to fill up any remaining space in the form. The TableLayoutPanel allows the form to be broken up into rows and columns. The __init__ method starts with the creation all of the controls -- first the TableLayoutPanel and FlowLayout Panel, followed by the WebBrowser, Label, TextBox, and Button. We set the TextBox's size to allow for a lengthier URL to be entered.
We introduce the StatusStrip at the bottom of the form where status information can be displayed. Within the StatusStrip a StatusStripLabel is created so that text information can be displayed. The StatusStripLabel will be used to display the URL of the site being displayed in the web browser.
Next the form's AcceptButton is set so that if the user hits enter, the button will be clicked.
We set the rows and columns for the TableLayoutPanel and add controls to it. We add the appropriate controls to the FlowLayoutPanel.
The OnMsgButtonClick method will be called in response to a button click. This method causes the URL supplied in the TextBox to be loaded. It displays the value in the TextBox that is in the StatusStripLabel, and the method clears the TextBox.
import clr
clr.AddReference("System.Windows.Forms")
clr.AddReference("System.Drawing")
from System.Windows.Forms import *
from System.Drawing import *
import System
from System import *
class FormV6(Form):
def __init__(self):
# setup TableLayoutPanel and FlowLayoutPanel
self._tableLayoutPanel1 = TableLayoutPanel(ColumnCount = 1,RowCount =
2, Dock = DockStyle.Fill)
self._flowLayoutPanel1 = FlowLayoutPanel(Dock = DockStyle.Fill)
self._webBrowser = WebBrowser(Dock = DockStyle.Fill)
self._label1 = Label(Text ='Enter Message')
self._txtMessage = TextBox(TabIndex = 0,Size = Size(200,20))
self._button1 = Button(Text ='Message')
# Setup ToolStrip and ToolStripLabel
self._StatusStrip1 = StatusStrip()
self._ToolStripStatusLabel1 = ToolStripStatusLabel()
self._StatusStrip1.Items.Add(self._ToolStripStatusLabel1)
self.Controls.Add(self._StatusStrip1)
self.AcceptButton = self._button1 # when the enter key is
pressed self._button1 will be clicked
self._button1.Click += self.OnmsgButtonClick
# Set TableLayoutPanel column and row styles and add FlowLayoutPanel and Web Browser
self._tableLayoutPanel1.ColumnStyles.Add(ColumnStyle(SizeType.Percent,
100.0))
self._tableLayoutPanel1.RowStyles.Add(RowStyle(SizeType.Absolute, 80.0))
self._tableLayoutPanel1.RowStyles.Add(RowStyle(SizeType.Percent, 100.0))
self._tableLayoutPanel1.Controls.Add(self._flowLayoutPanel1, 0, 0)
self._tableLayoutPanel1.Controls.Add(self._webBrowser, 0, 1)
# add controls that will be contained in FlowLayoutPanel
self._flowLayoutPanel1.Controls.Add(self._label1)
self._flowLayoutPanel1.Controls.Add(self._txtMessage)
self._flowLayoutPanel1.Controls.Add(self._button1)
self.Controls.Add(self._tableLayoutPanel1)
def OnmsgButtonClick(self,
*args):
self._webBrowser.Navigate(self._txtMessage.Text)
self._ToolStripStatusLabel1.Text = self._txtMessage.Text
self._txtMessage.Text = ""
Application.Run(FormV6())
1. Now let's try the Windows Form application by launching the IronPython script from a cmd.exe window:
ipyw.exe winforms\formV6.py
You should see the following window pop up on your screen. If you type in a valid URL and hit enter, the web browser control displays the selected web page.

Task 7 takes our basic form with a Label, TextBox, and a Button, but now we add a PictureBox control. We will leverage the approach from Task 6 and use a TableLayoutPanel and FlowLayoutPanel to make laying out our form easy. We will use the PictureBox to display a map. The user will enter a landmark or address in the TextBox, and we will use MapPoint Web Services to render a map of that location. We will be using a C# assembly named MapPointWebServiceProject.dll to provide access to MapPoint Web Services.
MapPointWebServiceProject.dll has already been built for you, but you are more than welcome to rebuild it. To build this DLL, open a command prompt and run "%WINDIR%\Microsoft.NET\Framework\v3.5\MSBuild /p:configuration=Release MapPointWebServiceProject.sln" from the winformsmappoint\winforms\ directory. Next simply copy winformsmappoint\winforms\bin\release\mappointwebservicesproject.dll to the winformsmappoint\ directory.
This task and the next contact Microsoft MapPoint servers remotely. Information sent to the MapPoint servers include a username and password along with your IP address and the text entered into the TextBox in the sample interface. No information is sent remotely until the user clicks on the "Get map" button or presses the enter key at which point the aforementioned data will be sent via SOAP over HTTP, which is not encrypted in any way.
We will be using a MapPoint UserID of 5200 and password of "ned68Fe". You can find info on applying for your own MapPoint Web Service account here http://www.microsoft.com/mappoint/en-us/default.aspx.
The first few lines of are the same as most of the previous examples. We add a reference to the MapPointWebServiceProject.dll so that we can use it inside our program and add the appropriate imports so we can use the classes in MapPointWebServiceProject as well as the underlying classes the MapPoint Web Services expose (such as Location and Route).
Next we create the TabelLayoutPanel and FlowLayoutPanel as well as creating the required controls such as Label, TextBox and Button. We setup the row and column characteristics for the TableLayoutPanel and add the controls to it. Then we add the controls to the FlowLayoutPanel.
All of the event handling is done in OnMsgButtonClick. When the button is pressed we create the MapPointWebServiceHelper by calling MapPointWebServiceHelper.GetInstance and pass it our UserID and password. Please note that when writing your own scripts you should never hard code usernames or passwords. We attempt to find a location using the MapPointWebServiceHelper.FindLocation method. If we are successful we call the MapPointWebServiceHelper.GetMap method and display the map. If the location can't be found we display a message stating we couldn't find the location. Finally we call application run to initiate the application.
import clr
clr.AddReference("System.Windows.Forms")
clr.AddReference("System.Drawing")
from System.Windows.Forms import *
from System.Drawing import *
import System
from System import *
clr.AddReferenceToFile("MapPointWebServiceProject.dll")
from MapPointWebServiceProject import *
from MapPointWebServiceProject.net.mappoint.staging import *
class FormV7(Form):
def __init__(self):
#
Create TableLayoutPanel and FlowLayoutPanel
self._tableLayoutPanel1 = TableLayoutPanel(ColumnCount = 1,Dock =
DockStyle.Fill,RowCount = 2)
self._flowLayoutPanel1 = FlowLayoutPanel(Dock = DockStyle.Fill)
#
Create Controls
self._pictureBox1 = PictureBox(Dock = DockStyle.Fill)
self._label1 = Label(Text ='Enter location:',AutoSize=True)
self._txtLocation = TextBox()
self._button1 = Button(Text ='Get map',AutoSize=True)
#
Setup TableLayoutPanel rows and columns and add controls
self._tableLayoutPanel1.ColumnStyles.Add(ColumnStyle(SizeType.Percent,
100.0))
self._tableLayoutPanel1.RowStyles.Add(RowStyle(SizeType.Absolute, 45.0))
self._tableLayoutPanel1.RowStyles.Add(RowStyle(SizeType.Percent, 100.0))
self._tableLayoutPanel1.Controls.Add(self._flowLayoutPanel1, 0, 0)
self._tableLayoutPanel1.Controls.Add(self._pictureBox1, 0, 1)
#
Add controls to FlowLayoutPanel
self._flowLayoutPanel1.Controls.Add(self._label1)
self._flowLayoutPanel1.Controls.Add(self._txtLocation)
self._flowLayoutPanel1.Controls.Add(self._button1)
self.AcceptButton = self._button1
self._button1.Click += self.OnMsgButtonClick
self.Controls.Add(self._tableLayoutPanel1)
def OnMsgButtonClick(self, *args):
try:
mapHelper = MapPointWebServiceHelper.GetInstance("5200", "ned68Fe")
loc
= mapHelper.FindLocation(self._txtLocation.Text)
if
loc:
self._pictureBox1.Image = mapHelper.GetMap(loc,
self._pictureBox1.Width, \
self._pictureBox1.Height, 4.0)
else:
MessageBox.Show("Address or location is not valid","Invalid Location")
except Exception, e:
MessageBox.Show(e.Message,"MapPoint Exception")
Application.Run(FormV7())
1. Now let's try the Windows Form application by launching the IronPython script from a cmd.exe window:
ipyw.exe winforms\formV7.py
You should see the following window pop up on your screen. If you type well known landmarks (Sears Tower, Navy Pier) or a valid address, then a map will be rendered. If you expand or contract the form and hit the Get Map button, the map will update to fit within the allocated space.

Task 8 takes our task 7 and expands it by allowing us to specify start and end locations, and then generate a route map. We will leverage previous tasks and use a TableLayoutPanel and FlowLayoutPanel to make laying out our form easy. We will use the PictureBox to display a map.
NOTE: See Task 7 to build and set up the MapPointWebServiceProject.dll for this task. If you performed task 7, you're fine to proceed.
Like task 7, this task contacts Microsoft MapPoint servers remotely. Information sent to the MapPoint servers include a username and password along with your IP address and the text entered into the TextBoxes in the sample interface. No information is sent remotely until the user clicks on the "Get map" button or presses the enter key at which point the aforementioned data will be sent via SOAP over HTTP, which is not encrypted in any way.
The first few lines of Task 8 are the same as most of the previous examples. We add a reference to the MapPointWebServiceProject.dll so that we can use it inside our program. Then we add the appropriate Python import statements so we can use the classes in MapPointWebServiceProject.dll and classes the MapPoint Web Services exposes (such as Location and Route).
Next we create the TabelLayoutPanel and two FlowLayoutPanel's. The first FlowLayoutPanel is for the control related to specifying the starting location. The second FlowLayoutPanel is for the Label, TextBox, and Button used to specify the ending location. We setup the row and column characteristics for the TableLayoutPanel and add the controls to it. Then we add the appropriate controls to our two FlowLayoutPanels.
All of the event handling is done within OnMsgButtonClick. When the button is pressed we create the MapPointWebServiceHelper by calling MapPointWebServiceHelper.GetInstance and pass it our UserID and password. We will be using a MapPoint UserID of 5200 and password of "ned68Fe". Please note that when writing your own scripts you should never hard code usernames or passwords. You can find out how to apply for your own MapPoint Web Service account here http://www.microsoft.com/mappoint/en-us/default.aspx. We attempt to find our starting location using the MapPointWebServiceHelper.FindLocation method. Next we attempt to find our ending location by calling the MapPointWebServiceHelper.FindLocation method again. If a location can't be found, the helper class throws an exception, which we handle by displaying a message. If both locations are found, then we will call MapPointWebServiceHelper.GetRouteMap to get our route map. If we are successful, we will display a route map, and if not, an error message is displayed.
Finally, we call application run to initiate the application.
import clr
clr.AddReference("System.Windows.Forms")
clr.AddReference("System.Drawing")
from System.Windows.Forms import *
from System.Drawing import *
import System
from System import *
clr.AddReferenceToFile("MapPointWebServiceProject.dll")
from MapPointWebServiceProject import *
from MapPointWebServiceProject.net.mappoint.staging import *
class FormV8(Form):
def __init__(self):
#
Create TableLayoutPanel and FlowLayoutPanel
self._tableLayoutPanel1 = TableLayoutPanel(ColumnCount = 1,Dock =
DockStyle.Fill,RowCount = 3)
self._flowLayoutPanel1 = FlowLayoutPanel(Dock = DockStyle.Fill)
self._flowLayoutPanel2 = FlowLayoutPanel(Dock = DockStyle.Fill)
#
controls for FlowLayout Start
self._label1 = Label(Text ='Enter start location:',AutoSize=True)
self._txtFromLocation = TextBox()
#
controls for FlowLayout End
self._label2 = Label(Text ='Enter end location:',AutoSize=True)
self._txtToLocation = TextBox()
self._button1 = Button(Text ='Get map',AutoSize=True)
#
this will hold our route map
self._pictureBox1 = PictureBox(Dock = DockStyle.Fill)
#
Setup TableLayoutPanel rows and columns and add controls
self._tableLayoutPanel1.ColumnStyles.Add(ColumnStyle(SizeType.Percent,
100.0))
self._tableLayoutPanel1.RowStyles.Add(RowStyle(SizeType.Absolute, 40.0))
self._tableLayoutPanel1.RowStyles.Add(RowStyle(SizeType.Absolute, 60.0))
self._tableLayoutPanel1.RowStyles.Add(RowStyle(SizeType.Percent, 100.0))
self._tableLayoutPanel1.Controls.Add(self._flowLayoutPanel1, 0, 0)
self._tableLayoutPanel1.Controls.Add(self._flowLayoutPanel2, 0, 1)
self._tableLayoutPanel1.Controls.Add(self._pictureBox1, 0, 2)
#
Add controls to FlowLayoutPanel Start
self._flowLayoutPanel1.Controls.Add(self._label1)
self._flowLayoutPanel1.Controls.Add(self._txtFromLocation)
#
Add controls to FlowLayoutPanel End
self._flowLayoutPanel2.Controls.Add(self._label2)
self._flowLayoutPanel2.Controls.Add(self._txtToLocation)
self._flowLayoutPanel2.Controls.Add(self._button1)
self.AcceptButton = self._button1
self._button1.Click += self.OnMsgButtonClick
self.Controls.Add(self._tableLayoutPanel1)
def OnMsgButtonClick(self,
*args):
try:
mapHelper = MapPointWebServiceHelper.GetInstance("5200", "ned68Fe")
locFrom = mapHelper.FindLocation(self._txtFromLocation.Text)
locTo = mapHelper.FindLocation(self._txtToLocation.Text)
myRoute = mapHelper.GetRoute(locFrom, locTo)
self._pictureBox1.Image = mapHelper.GetRouteMap(myRoute,
self._pictureBox1.Width, self._pictureBox1.Height)
except Exception, e:
MessageBox.Show(e.Message,"MapPoint Exception")
Application.Run(FormV8())
1. Now let's try the Windows Form application by launching the IronPython script from a cmd.exe window:
ipyw.exe winforms\formV8.py
Note, please be patient as there are four web service calls. After clicking get map it takes a little time to render the map.
You should see the following window pop up on your screen. If you type a well known landmark (Sears Tower, Navy Pier) or a valid address for the start and end locations, then a route map will be rendered. If you expand or contract the form and hit the Get Map button, the map will update to fit within the allocated space.

Tutorial Summary
In this tutorial you learned more about building Windows Forms applications using IronPython. You started with the most basic Winforms application - an empty form with the title set - and progressed through a series of samples that showed how to build increasingly more complex Winforms user interfaces via IronPython. You learned that even sophisticated GUIs could be easily developed using basic controls such as Label, TextBox, Button, PictureBox in conjunction with advanced layout controls like TableLayoutPanel and FlowLayoutPanel.