Combine Virtual Earth and Silverlight into one Project.
Subjects:
Load VE Map in a html page.
Create/Edit a Simple Silverlight Control.
Use Expression Blend for editing templates and styles.
Communication between Javascript and Silverlight.
Basic functions in Virtual Earth
1. Create a New Silverlight Project
2. Set html page as Start Page.
3. Add Virtual Earth Map
Add VE JavaScript in html <head>:
<script type="text/javascript" src="http://dev.virtualearth.net/mapcontrol/mapcontrol.ashx?v=6.1"></script>
<script type="text/javascript"> var map = null; function GetMap() { map = new VEMap('myMap'); map.LoadMap(new VELatLong(47.6, -122.33), 10 ,'h' ,false); } </script>
Add a div for the Map in <body>
<div id="myMap" style="position:absolute; height:100%; width:100%;"> </div>
Loading Map at startup
<body onload="GetMap();">
4. Make Silverlight Transparent and Windowless
<div id="silverlightControlHost";; "height:115px; width:100%; position: absolute; top: auto; right: 0px; bottom: 0px; left: 0px;"> <object data="data:application/x-silverlight," type="application/x-silverlight-2-b2" width="100%" height="100%"> <param name="source" value="ClientBin/VESilverlight.xap"/> <param name="onerror" value="onSilverlightError" /> <param name="background" value="transparent" /> <param name="windowless" value="true" /> <a href="http://go.microsoft.com/fwlink/?LinkID=115261" style="text-decoration: none;"> <img src="http://go.microsoft.com/fwlink/?LinkId=108181" alt="Get Microsoft Silverlight" style="border-style: none"/> </a> </object> <iframe style='visibility:hidden;height:0;width:0;border:0px'></iframe> </div>
5. Editing the Silverlight Control
Open project with Microsoft Expression Blend 2.5 June 2008 Preview
Change UserControl properties:
Change LayoutControl properties:
Test the Project
6. Add a button style in App.xaml
<Application xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" mc:Ignorable="d" x:Class="VESilverlight.App" xmlns:vsm="clr-namespace:System.Windows;assembly=System.Windows" > <Application.Resources> <Style x:Key="ButtonStyle1" TargetType="Button"> <Setter Property="IsEnabled" Value="true"/> <Setter Property="IsTabStop" Value="true"/> <Setter Property="Background" Value="#FF003255"/> <Setter Property="Foreground" Value="#FF313131"/> <Setter Property="MinWidth" Value="5"/> <Setter Property="MinHeight" Value="5"/> <Setter Property="Margin" Value="0"/> <Setter Property="HorizontalContentAlignment" Value="Center"/> <Setter Property="VerticalContentAlignment" Value="Center"/> <Setter Property="Cursor" Value="Arrow"/> <Setter Property="TextAlignment" Value="Left"/> <Setter Property="TextWrapping" Value="NoWrap"/> <Setter Property="FontSize" Value="11"/> <Setter Property="Template"> <Setter.Value> <ControlTemplate TargetType="Button"> <Grid x:Name="grid" RenderTransformOrigin="0.5,0.5" Width="40"> <Grid.Resources> <Color x:Key="LinearBevelLightStartColor">#FCFFFFFF</Color> <Color x:Key="LinearBevelLightEndColor">#F4FFFFFF</Color> <Color x:Key="LinearBevelDarkStartColor">#E0FFFFFF</Color> <Color x:Key="LinearBevelDarkEndColor">#B2FFFFFF</Color> <Color x:Key="MouseOverLinearBevelDarkEndColor">#7FFFFFFF</Color> <Color x:Key="HoverLinearBevelLightStartColor">#FCFFFFFF</Color> <Color x:Key="HoverLinearBevelLightEndColor">#EAFFFFFF</Color> <Color x:Key="HoverLinearBevelDarkStartColor">#D8FFFFFF</Color> <Color x:Key="HoverLinearBevelDarkEndColor">#4CFFFFFF</Color> <Color x:Key="CurvedBevelFillStartColor">#B3FFFFFF</Color> <Color x:Key="CurvedBevelFillEndColor">#3CFFFFFF</Color> <SolidColorBrush x:Key="BorderBrush" Color="#FF000000"/> <SolidColorBrush x:Key="AccentBrush" Color="#FFFFFFFF"/> <SolidColorBrush x:Key="DisabledBrush" Color="#A5FFFFFF"/> <LinearGradientBrush x:Key="FocusedStrokeBrush" EndPoint="0.5,1" StartPoint="0.5,0"> <GradientStop Color="#B2FFFFFF" Offset="0"/> <GradientStop Color="#51FFFFFF" Offset="1"/> <GradientStop Color="#66FFFFFF" Offset="0.325"/> <GradientStop Color="#1EFFFFFF" Offset="0.325"/> </LinearGradientBrush> </Grid.Resources> <Grid.RowDefinitions> <RowDefinition Height="*"/> <RowDefinition Height="*"/> </Grid.RowDefinitions> <Grid.RenderTransform> <TransformGroup> <ScaleTransform/> <SkewTransform/> <RotateTransform/> <TranslateTransform/> </TransformGroup> </Grid.RenderTransform> <vsm:VisualStateManager.VisualStateGroups> <vsm:VisualStateGroup x:Name="CommonStates"> <vsm:VisualStateGroup.Transitions> <vsm:VisualTransition Duration="00:00:00.2000000" From="Normal" To="MouseOver"/> <vsm:VisualTransition Duration="00:00:00.4000000" From="MouseOver" To="Normal"/> </vsm:VisualStateGroup.Transitions> <vsm:VisualState x:Name="Normal"/> <vsm:VisualState x:Name="MouseOver"> <Storyboard> <DoubleAnimationUsingKeyFrames BeginTime="00:00:00" Duration="00:00:00.0010000" Storyboard.TargetName="rectangle" Storyboard.TargetProperty="(UIElement.Opacity)"> <SplineDoubleKeyFrame KeyTime="00:00:00" Value="0.8"/> </DoubleAnimationUsingKeyFrames> </Storyboard> </vsm:VisualState> <vsm:VisualState x:Name="Pressed"> <Storyboard> <DoubleAnimationUsingKeyFrames BeginTime="00:00:00" Duration="00:00:00.0010000" Storyboard.TargetName="grid" Storyboard.TargetProperty="(UIElement.RenderTransform).(TransformGroup.Children)[3].(TranslateTransform.X)"> <SplineDoubleKeyFrame KeyTime="00:00:00" Value="1.5"/> </DoubleAnimationUsingKeyFrames> <DoubleAnimationUsingKeyFrames BeginTime="00:00:00" Duration="00:00:00.0010000" Storyboard.TargetName="grid" Storyboard.TargetProperty="(UIElement.RenderTransform).(TransformGroup.Children)[3].(TranslateTransform.Y)"> <SplineDoubleKeyFrame KeyTime="00:00:00" Value="1.5"/> </DoubleAnimationUsingKeyFrames> </Storyboard> </vsm:VisualState> <vsm:VisualState x:Name="Disabled"> <Storyboard/> </vsm:VisualState> </vsm:VisualStateGroup> <vsm:VisualStateGroup x:Name="FocusStates"> <vsm:VisualState x:Name="Focused"> <Storyboard/> </vsm:VisualState> <vsm:VisualState x:Name="Unfocused"> <Storyboard/> </vsm:VisualState> </vsm:VisualStateGroup> </vsm:VisualStateManager.VisualStateGroups> <Rectangle x:Name="Background" Grid.RowSpan="2" RadiusX="4" RadiusY="4"/> <ContentPresenter HorizontalContentAlignment="{TemplateBinding HorizontalContentAlignment}" Padding="{TemplateBinding Padding}" VerticalContentAlignment="{TemplateBinding VerticalContentAlignment}" Margin="4,5,4,4" Grid.RowSpan="2" Content="{TemplateBinding Content}" ContentTemplate="{TemplateBinding ContentTemplate}" TextAlignment="{TemplateBinding TextAlignment}" TextDecorations="{TemplateBinding TextDecorations}" TextWrapping="{TemplateBinding TextWrapping}"/> <Rectangle RadiusX="4" RadiusY="4" Grid.RowSpan="2" Margin="1,1,1,5" x:Name="rectangle" Opacity="0.4"> <Rectangle.OpacityMask> <LinearGradientBrush EndPoint="0.5,1" StartPoint="0.5,0"> <GradientStop Color="#FFFFFFFF"/> <GradientStop Color="#19FFFFFF" Offset="1"/> </LinearGradientBrush> </Rectangle.OpacityMask> <Rectangle.Fill> <LinearGradientBrush EndPoint="0.5,1" StartPoint="0.5,0"> <GradientStop Color="#FFFFFFFF"/> <GradientStop Color="#FFFFFFFF" Offset="1"/> </LinearGradientBrush> </Rectangle.Fill> </Rectangle> </Grid> </ControlTemplate> </Setter.Value> </Setter> </Style> </Application.Resources> </Application>
7. Insert a button in LayoutRoot and apply the style
8. Edit Button Style Template
Change grid properties
9. Add 2 TextBlocks
10. Add a Slider Control and edit the template
Edit HorizontalThumb Template
Add another one Slider
Change the SmallChange value
10. Add Code for Button Find Click
Private Sub btnFind_Click(ByVal sender As Object, ByVal e As System.Windows.RoutedEventArgs) Handles btnFind.Click Dim Culture = Me.sliderculture.Value Dim Sports = Me.slidersports.Value HtmlPage.Window.Invoke("GenerateTourGuide", New Object() {Culture, Sports}) End Sub
11. Add Javascript for communication between html and Silverlight
We need a layer for the points, an array to store locations for routing and a variable for results number.
var slTourGuidePoints = null; var TourGuideLocations = null; var ResultsNum;
Initialize the layer in function GetMap()
slTourGuidePoints = new VEShapeLayer();
map.AddShapeLayer(slTourGuidePoints);
Function GenerateTourGuide.
function GenerateTourGuide(CultureVal1,SportsVal1) { slTourGuidePoints.DeleteAllShapes(); TourGuideLocations = new Array(); ResultsNum=CultureVal1 + SportsVal1; var LL=map.GetCenter(); if(CultureVal1 > 0) { SearchPoints('Culture',CultureVal1); } if(SportsVal1 > 0) { SearchPoints('Sports',SportsVal1); } }
Function SearchPoints.
function SearchPoints(Category,Value) { var what = Category; var numberOfResults = Value; try { map.Find(what,null, null, null, 0, numberOfResults, false, false, false, null, GetCoordinates); } catch(e) { alert(e.message); } } function GetCoordinates(layer, resultsArray, places, hasMore, veErrorMessage) { //alert(resultsArray.length); for(var i = 0;i < resultsArray.length; i++) { var ll = resultsArray[i].LatLong; var phone = resultsArray[i].Phone; var name = resultsArray[i].Name; var descr = resultsArray[i].Description; //alert(ll); var shape = new VEShape(VEShapeType.Pushpin,ll); var infobox = "<div style='width:309px;'>\Phone: "+ phone +"\<br>"+"\Description: "+ descr +"\<br>"; map.ClearInfoBoxStyles(); shape.SetTitle(name); shape.SetDescription(infobox); shape.SetCustomIcon("http://i243.photobucket.com/albums/ff300/kxalv/iconBluetack.png"); slTourGuidePoints.AddShape(shape); TourGuideLocations.push(ll); }
//At the End Calculate the Routing for Locations if(TourGuideLocations.length == ResultsNum) { var options = new VERouteOptions; // Otherwise what's the point? options.DrawRoute = true; // So the map doesn't change: options.SetBestMapView = true; // Call this function when map route is determined: //options.RouteCallback = ShowTurns; // Show as miles //options.DistanceUnit = VERouteDistanceUnit.Mile; // Show the disambiguation dialog options.ShowDisambiguation = true; //alert(TourGuideLocations.length); map.GetDirections(TourGuideLocations, options); }
Results