Dec 14

The purpose of this post is to create an interactive map that allows you to select multiple regions of a map. To do this we create a customized template based on a "ToggleButton. Indeed, thanks to "ToggleButton" we're going to manage several status as "Checked" and "Unchecked" which will serve us whether the region is selected or not.
For this post we'll use a map of Belgium where you can select multiple provinces. Then, all selected provinces will be added to a list.

Step 1 Creation of template for “ToggleButton”

The first step in creating this map is to add a “ToggleButton”, then click in the list at the top left and select:

Edit Template --> Create Empty…

image

To follow the boundaries of the map we use the "Pen" to define a "Path". Since an element can be amended only by a “VisualStateGroup”, we will create 2 “Path”. One for the group “CommonStates” and one for the group “CheckStates”.

image

The 2 "Path" are identical no matter the data they contain.

<Path Fill="White" Stretch="Fill" Stroke="Black" Height="68" HorizontalAlignment="Left" Margin="35.5,24.5,0,0" VerticalAlignment="Top" Width="75" UseLayoutRounding="False" Data="M64,25 L110,55 L36,92 z"/>
<Path Fill="Black" Stretch="Fill" Stroke="Black" Height="68" HorizontalAlignment="Left" Margin="35.5,24.5,0,0" VerticalAlignment="Top" Width="75" UseLayoutRounding="False" Data="M64,25 L110,55 L36,92 z"/>

For simplicity I named the "Path", "PathCommonStates" and "PathCheckStates", and I Initialize their opacities to 0.

image

image

Then I select the path "PathCommonState" and click on the "MouseOver" state to change the opacity to 30%.

image

I do the same thing with the path "PathCheckStates", I click on "Checked" state to set the opacity to 30%.
I will then modify the code to add "TemplateBinding" properties. It gives this:

<UserControl.Resources>
	<ControlTemplate x:Key="MapButton" TargetType="ToggleButton">
		<Grid>
			<VisualStateManager.VisualStateGroups>
				<VisualStateGroup x:Name="CommonStates">
					<VisualState x:Name="Normal"/>
					<VisualState x:Name="MouseOver">
						<Storyboard>
							<DoubleAnimationUsingKeyFrames BeginTime="00:00:00" Duration="00:00:00.0010000" Storyboard.TargetName="PathCommonStates" Storyboard.TargetProperty="(UIElement.Opacity)">
								<EasingDoubleKeyFrame KeyTime="00:00:00" Value="0.3"/>
							</DoubleAnimationUsingKeyFrames>
						</Storyboard>
					</VisualState>
					<VisualState x:Name="Pressed"/>
					<VisualState x:Name="Disabled"/>
				</VisualStateGroup>
				<VisualStateGroup x:Name="CheckStates">
					<VisualState x:Name="Unchecked"/>
					<VisualState x:Name="Indeterminate"/>
					<VisualState x:Name="Checked">
						<Storyboard>
							<DoubleAnimationUsingKeyFrames BeginTime="00:00:00" Duration="00:00:00.0010000" Storyboard.TargetName="PathCheckStates" Storyboard.TargetProperty="(UIElement.Opacity)">
								<EasingDoubleKeyFrame KeyTime="00:00:00" Value="0.3"/>
							</DoubleAnimationUsingKeyFrames>
						</Storyboard>
					</VisualState>
				</VisualStateGroup>
				<VisualStateGroup x:Name="FocusStates">
					<VisualState x:Name="Unfocused"/>
					<VisualState x:Name="Focused"/>
				</VisualStateGroup>
			</VisualStateManager.VisualStateGroups>
			<Path x:Name="PathCommonStates" Opacity="0" Fill="White" Stretch="Fill" Height="{TemplateBinding Height}" HorizontalAlignment="{TemplateBinding HorizontalAlignment}" Margin="{TemplateBinding Margin}" VerticalAlignment="{TemplateBinding VerticalAlignment}" Width="{TemplateBinding Width}" UseLayoutRounding="{TemplateBinding UseLayoutRounding}" Data="{TemplateBinding Content}"/>
			<Path x:Name="PathCheckStates" Opacity="0" Fill="Black" Stretch="Fill" Height="{TemplateBinding Height}" HorizontalAlignment="{TemplateBinding HorizontalAlignment}" Margin="{TemplateBinding Margin}" VerticalAlignment="{TemplateBinding VerticalAlignment}" Width="{TemplateBinding Width}" UseLayoutRounding="{TemplateBinding UseLayoutRounding}" Data="{TemplateBinding Content}"/>
		</Grid>
	</ControlTemplate>
</UserControl.Resources>

<Grid x:Name="LayoutRoot" Background="White">
	<ToggleButton HorizontalAlignment="Left" VerticalAlignment="Top" Content="ToggleButton" Template="{StaticResource MapButton}"/>
</Grid>

Note that the property "Data" is doing a "TemplateBinding" on the property "Content". Indeed, we will use the property "Content" of "ToggleButton" to the boundaries of each region.

Step 2: Adding the map into the project


After the creation of “ToggleButton”, we will simply add the map into the project.

Step 3: Establish the boundaries of each region


The third step is creating the boundaries of each region, we will then take the "Pen" and create a "Path" point by point all around the region. Like this:

image

Then we copy all the properties of the "Path" in the customized "ToggleButton" except that "Data" property is renamed "Content" property and "Stretch" is deleted.
Example:

<Path Stretch="Fill" Height="95.333" Margin="282.667,128.5,216.667,0" VerticalAlignment="Top" UseLayoutRounding="False" Data="…"/>

Becomes:

<ToggleButton Template="{StaticResource MapButton}" Height="95.333" Margin="282.667,128.5,216.667,0" VerticalAlignment="Top" UseLayoutRounding="False" Content="…"/>

 

You can download the full code:

Tags:

Comments

Irwin Fletcher

Posted on Friday, 8 January 2010 11:51

This is a great post, it helped me get a better handle on the map application that I am messing around with.  How would you implement a zoom and pan feature with a XAML image?

Bruno Leonardo

Posted on Wednesday, 30 June 2010 14:27

What a great post! It helped me a lot!

Bruno Leonardo

Posted on Thursday, 1 July 2010 12:33

I'm having a problem when puting this to an asp page. I set the boundaries, but when I run the page, the boundarie is not aligned with my map. Could you help me solve this problem?

Houses

Posted on Wednesday, 14 July 2010 08:14

Just in case you didn't know... your site looks very peculiar in Chameleon on a Mac

Blog Literature

Posted on Thursday, 22 July 2010 16:59

I didn't use it yet but now after reading your tutorial, i am going to add it in my site. I hope it 'll be a very nice experience for me. Infact i have learn a lot from your blog. Thanks for sharing such valuable stuff with us.

Grande Dunes

Posted on Saturday, 24 July 2010 22:41

Gregoly Despain

Posted on Tuesday, 10 August 2010 00:32

I just about passed your website up in Bing but now I'm glad I clicked on through and got to browse through it. Thanks for taking the time to discuss this, I feel strongly about it and love learning more on this topic.

computer repair st. paul

Posted on Tuesday, 10 August 2010 06:15

Interesting.  Thanks for sharing!

Larry Barranger

Posted on Tuesday, 10 August 2010 10:01

I am viewing this site on my iPad,  and I must say,  the resolution on this thing is really nice!

sssssonya

Posted on Wednesday, 11 August 2010 11:33

great post

learning laptop

Posted on Sunday, 15 August 2010 12:33

Is there a more accurate way of creating the point to point paths?

Leandro Cocker

Posted on Sunday, 15 August 2010 20:01

MMM...Maby considere to put here more silverlight pic

restaurant city tips

Posted on Sunday, 15 August 2010 22:24

Hey, I just found this article through Bing. I like the briefing affirmed by the article. I'm going to subscribe to your feeds aiming to read again. Please if everyone can go over my blog, HackingEdge.com.

Impact Crusher

Posted on Wednesday, 18 August 2010 04:53

I am a. NET beginner, your article helped me a lot, I will focus on your blog, thanks!

Jenn Air Outdoor Grills

Posted on Thursday, 2 September 2010 16:15

I'm glad I found it.

Add comment




  Country flag

biuquote
Loading