Just another side of me

My name is Veri, MSP from ITB. Enjoy my blog...
See also: Other Geeks@INDC

Bing Maps and OData (part 5)

This is the last post from a series that talked about Bing Maps and OData. I’ve told you how to retrieve and how to consume the OData in here, how to create the ViewModel that will be used for data binding in here, and how to create the Child Window in here. Finally, in this post I will show you how to make the main UX for the NerdDinner web application. Just copy and paste the code below to your MainPage.xaml.

   1: <UserControl x:Class="BingMapsOData.MainPage"
   2:     xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
   3:     xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
   4:     xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
   5:     xmlns:controls="clr-namespace:System.Windows.Controls;assembly=System.Windows.Controls"
   6:     xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
   7:     xmlns:local="clr-namespace:BingMapsOData"
   8:     xmlns:m="clr-namespace:Microsoft.Maps.MapControl;assembly=Microsoft.Maps.MapControl"
   9:     xmlns:i="clr-namespace:System.Windows.Interactivity;assembly=System.Windows.Interactivity"
  10:     mc:Ignorable="d"
  11:     d:DesignHeight="300" d:DesignWidth="400">
  12:     
  13:     <UserControl.Resources>
  14:         <DataTemplate x:Key="DinnerTemplate">
  15:             <m:Pushpin Name="DinnerPushpin" m:MapLayer.Position="{Binding Location}" Content="{Binding Attendees}">
  16:                 <i:Interaction.Triggers>
  17:                     <i:EventTrigger EventName="MouseLeftButtonDown">
  18:                         <local:ShowChildWindowAction ChildWindowType="BingMapsOData.DetailsChildWindow"/>
  19:                     </i:EventTrigger>
  20:                 </i:Interaction.Triggers>
  21:                 <ToolTipService.ToolTip>
  22:                     <StackPanel>
  23:                         <StackPanel Margin="2" Orientation="Horizontal">
  24:                             <Image Source="Images/dinner.png" Width="16" Height="16"/>
  25:                             <TextBlock Text="{Binding Title}" Padding="2" FontWeight="Bold" TextWrapping="Wrap"/>
  26:                         </StackPanel>
  27:                         <TextBlock Text="{Binding Date}" Padding="2" Margin="2" TextWrapping="Wrap"/>
  28:                         <TextBlock Text="{Binding Address}" Padding="2" Margin="2" TextWrapping="Wrap"/>
  29:                         <TextBlock Text="Click Pushpin for details" Foreground="Gray" Padding="2" Margin="2" TextWrapping="Wrap"/>
  30:                     </StackPanel>
  31:                 </ToolTipService.ToolTip>
  32:             </m:Pushpin>
  33:         </DataTemplate>
  34:     </UserControl.Resources>
  35:  
  36:     <Grid x:Name="LayoutRoot" Background="Black">
  37:         <Grid.RowDefinitions>
  38:             <RowDefinition Height="40"/>
  39:             <RowDefinition Height="37"/>
  40:             <RowDefinition Height="*"/>
  41:             <RowDefinition Height="20"/>
  42:         </Grid.RowDefinitions>
  43:         <Grid.ColumnDefinitions>
  44:             <ColumnDefinition />
  45:             <ColumnDefinition Width="Auto" />
  46:         </Grid.ColumnDefinitions>
  47:         
  48:         <m:Map x:Name="dinnerMap"
  49:                Grid.Row="0" Grid.RowSpan="3"
  50:                Grid.Column="0" Grid.ColumnSpan="2"
  51:                CacheMode="BitmapCache"
  52:                CredentialsProvider="{StaticResource MyCredentials}"
  53:                Mode="AerialWithLabels"
  54:                NavigationVisibility="Collapsed">
  55:             <m:MapItemsControl x:Name="dinnerList"
  56:                                ItemTemplate="{StaticResource DinnerTemplate}"
  57:                                ItemsSource="{Binding Dinners}">
  58:             </m:MapItemsControl>
  59:         </m:Map>
  60:  
  61:         <StackPanel Grid.Row="0" Grid.Column="0" Background="Black" Opacity="0.8">
  62:             <StackPanel Orientation="Horizontal">
  63:                 <TextBlock Text="Nerd Dinner Browser" FontSize="20" Padding="6" Foreground="White"/>
  64:                 <TextBlock Text="{Binding Status}" FontSize="14" Padding="12" Foreground="LightGray" Name="txtStatus" >
  65:                     <TextBlock.Triggers>
  66:                     </TextBlock.Triggers>
  67:                 </TextBlock>
  68:             </StackPanel>
  69:         </StackPanel>
  70:  
  71:         <StackPanel Grid.Row="1" Grid.Column="0">
  72:             <Border BorderThickness="1" BorderBrush="LightGray" Background="LightGray" CornerRadius="5" Padding="5" Margin="1">
  73:                 <StackPanel Orientation="Horizontal">
  74:                     <TextBlock Text="Dinners From " Padding="4"/>
  75:                     <controls:DatePicker SelectedDate="{Binding From, Mode=TwoWay}" Name="dtFrom" Width="130"/>
  76:                     <TextBlock Text=" To " Padding="4"/>
  77:                     <controls:DatePicker SelectedDate="{Binding To, Mode=TwoWay}" Name="dtTo" Width="130"/>
  78:                     <TextBlock Text=" Near " Padding="4"/>
  79:                     <TextBox Name="txtPlace" ToolTipService.ToolTip="Optional, Leave blank for a high level view" Width="130"/>
  80:                     <Button Name="SearchDinners" Click="SearchDinners_Click" Margin="1" Padding="3">
  81:                         <StackPanel Orientation="Horizontal" >
  82:                             <Image Source="Images/dinner.png" Width="16" Height="16"/>
  83:                             <TextBlock Text=" Grab The Dinners "/>
  84:                         </StackPanel>
  85:                     </Button>
  86:                     <TextBlock Width="6"/>
  87:                     <StackPanel Background="Gray" Width="2" Margin="2"/>
  88:                 </StackPanel>
  89:             </Border>
  90:         </StackPanel>
  91:  
  92:         <Canvas x:Name="cMiniMap" 
  93:                 Width="150" 
  94:                 Height="150" 
  95:                 HorizontalAlignment="Left" Margin="10,10,0,0" VerticalAlignment="Top" Grid.Row="2" >
  96:             <m:Map x:Name="MiniMap" 
  97:                    CredentialsProvider="{StaticResource MyCredentials}"
  98:                    CacheMode="BitmapCache"
  99:                    Width="150" 
 100:                    Height="150" 
 101:                    Mode="Road" 
 102:                    NavigationVisibility="Collapsed" 
 103:                    ScaleVisibility="Collapsed" 
 104:                    LogoVisibility="Collapsed"
 105:                    CopyrightVisibility="Collapsed" Foreground="{x:Null}">
 106:                 <m:Map.Clip>
 107:                     <EllipseGeometry RadiusX="69" RadiusY="69" Center="75,75" />
 108:                 </m:Map.Clip>
 109:             </m:Map>
 110:             <Ellipse Width="150" Height="150" Stroke="#CC4C4C4C" StrokeThickness="6" Margin="0,0,0,0" CacheMode="BitmapCache" />
 111:             <Ellipse Height="10" Width="10" HorizontalAlignment="Center" VerticalAlignment="Center" Margin="70,70,0,0" x:Name="ellipse" Fill="#CC205A5B" />
 112:         </Canvas>
 113:  
 114:         <Canvas x:Name="cNavControl" 
 115:                 Width="100" 
 116:                 HorizontalAlignment="Left" 
 117:                 VerticalAlignment="Top" Grid.Row="2" Margin="60,155,0,0" Grid.RowSpan="3" >
 118:             <StackPanel Width="50">
 119:                 <Ellipse x:Name="ePan" Fill="#CC4C4C4C" Height="50" Canvas.ZIndex="1" Width="50"/>
 120:                 <Path x:Name="pathMiniMap" Stretch="Fill" Stroke="#CCFFFFFF" Height="195" Margin="-50,-195,-50,0" UseLayoutRounding="False" Canvas.ZIndex="1" Data="M75,0.5 C116.14521,0.5 149.5,33.854782 149.5,75 C149.5,111.64496 123.04255,142.11044 88.187729,148.3364 L86.852966,148.55754 L87.70414,149.04695 C94.776031,153.34393 99.5,161.1203 99.5,170 C99.5,183.53098 88.530975,194.5 75,194.5 C61.469025,194.5 50.5,183.53098 50.5,170 C50.5,161.1203 55.223965,153.34393 62.29586,149.04695 L63.14703,148.55754 L61.812263,148.3364 C26.957447,142.11044 0.5,111.64496 0.5,75 C0.5,33.854782 33.854786,0.5 75,0.5 z"/>
 121:                 <Grid x:Name="gridPan" Height="50" Margin="0,-50,0,0" Width="50" Canvas.ZIndex="1">
 122:                     <Grid.RowDefinitions>
 123:                         <RowDefinition Height="12"/>
 124:                         <RowDefinition Height="26" />
 125:                         <RowDefinition Height="12"/>
 126:                     </Grid.RowDefinitions>
 127:                     <Grid.ColumnDefinitions>
 128:                         <ColumnDefinition Width="12" />
 129:                         <ColumnDefinition Width="26" />
 130:                         <ColumnDefinition Width="12"/>
 131:                     </Grid.ColumnDefinitions>
 132:  
 133:                     <Image Source="Images/PanUp.png" Stretch="Fill" Grid.Row="0" Grid.Column="1" HorizontalAlignment="Center" VerticalAlignment="Top" Height="20" Margin="0,5,0,0" Width="34" MouseLeftButtonDown="PanMapUp"/>
 134:                     <Image Source="Images/PanLeft.png" Stretch="Fill" Grid.Row="1" HorizontalAlignment="Left" VerticalAlignment="Center" Width="20" Margin="5,0,0,0" Height="34" MouseLeftButtonDown="PanMapLeft"/>
 135:                     <Image Source="Images/PanRight.png" Stretch="Fill" Grid.Row="1" Grid.Column="2" HorizontalAlignment="Right" VerticalAlignment="Center" Width="20" Margin="0,0,5,0" Height="34" MouseLeftButtonDown="PanMapRight"/>
 136:                     <Image Source="Images/PanDown.png" Stretch="Fill" Height="20" Margin="0,0,0,5" VerticalAlignment="Bottom" Grid.Row="2" Grid.Column="1" HorizontalAlignment="Center" Width="34" MouseLeftButtonDown="PanMapDown"/>
 137:                 </Grid>
 138:                 <Border Margin="0,5,0,0" Width="15" Background="#CC4C4C4C" BorderThickness="1,1,1,0" BorderBrush="#CCFFFFFF" Height="15">
 139:                     <TextBlock Foreground="White" HorizontalAlignment="Center" Text="+" MouseLeftButtonDown="ZoomIn" VerticalAlignment="Center"/>
 140:                 </Border>
 141:                 <Border Height="160" HorizontalAlignment="Center" Margin="0" Width="15" RenderTransformOrigin="0.5,0.5" BorderThickness="1" Background="#CC4C4C4C" BorderBrush="#CCFFFFFF">
 142:                     <Slider x:Name="sldZoom" Orientation="Vertical" Maximum="21" Minimum="1" Height="150" Value="0" HorizontalAlignment="Center" Margin="0" SmallChange="1" BorderBrush="{x:Null}" BorderThickness="1" Width="15" Canvas.ZIndex="1" Foreground="{x:Null}" >
 143:                         <i:Interaction.Behaviors>
 144:                             <local:SnappingSlider/>
 145:                         </i:Interaction.Behaviors>
 146:                     </Slider>
 147:                 </Border>
 148:                 <Border Margin="0,0,0,5" Width="15" Background="#CC4C4C4C" BorderThickness="1,0,1,1" BorderBrush="#CCFFFFFF" Height="15">
 149:                     <TextBlock Foreground="White" HorizontalAlignment="Center" Text="-" MouseLeftButtonDown="ZoomOut" VerticalAlignment="Center"/>
 150:                 </Border>
 151:                 <Border Margin="0" Width="50" Background="#CC4C4C4C" BorderThickness="1" BorderBrush="#CCFFFFFF">
 152:                     <TextBlock Foreground="White" HorizontalAlignment="Center" Text="Road" MouseLeftButtonDown="MapStyleRoad" VerticalAlignment="Center"/>
 153:                 </Border>
 154:                 <Border Height="15" Margin="0" Width="50" Background="#CC4C4C4C" BorderThickness="1,0,1,1" BorderBrush="#CCFFFFFF">
 155:                     <TextBlock Foreground="White" HorizontalAlignment="Center" Text="Aerial" MouseLeftButtonDown="MapStyleAerial" VerticalAlignment="Center"/>
 156:                 </Border>
 157:                 <Border Height="15" Margin="0" Width="50" Background="#CC4C4C4C" BorderThickness="1,0,1,1" BorderBrush="#CCFFFFFF">
 158:                     <TextBlock Foreground="White" HorizontalAlignment="Center" Text="Hybrid" MouseLeftButtonDown="MapStyleHybrid" VerticalAlignment="Center"/>
 159:                 </Border>
 160:             </StackPanel>
 161:         </Canvas>
 162:  
 163:         <StackPanel Orientation="Horizontal" Grid.Row="3" HorizontalAlignment="Center">
 164:             <HyperlinkButton NavigateUri="http://students.netindonesia.net/blogs/veri" Content="My Blog" TargetName="_blank" FontFamily="Verdana" FontSize="12" Foreground="#FFFFFFFF"/>
 165:             <TextBlock Foreground="White" Text="|"></TextBlock>
 166:             <HyperlinkButton NavigateUri="http://twitter.com/vferdiansyah" Content="Twitter" TargetName="_blank" FontFamily="Verdana" FontSize="12" Foreground="#FFFFFFFF"/>
 167:             <TextBlock Foreground="White" Text="|"></TextBlock>
 168:             <HyperlinkButton NavigateUri="http://www.facebook.com/verif" Content="Facebook" TargetName="_blank" FontFamily="Verdana" FontSize="12" Foreground="#FFFFFFFF"/>
 169:             <TextBlock Foreground="White" Text="|"></TextBlock>
 170:             <HyperlinkButton NavigateUri="http://www.linkedin.com/pub/veri-ferdiansyah/21/a14/593" Content="Linked In" TargetName="_blank" FontFamily="Verdana" FontSize="12" Foreground="#FFFFFFFF"/>
 171:         </StackPanel>
 172:     </Grid>
 173: </UserControl>

After that, you also need to copy and paste the code below to your MainPage.xaml.cs.

   1: using System;
   2: using System.Windows;
   3: using System.Windows.Browser;
   4: using System.Windows.Controls;
   5: using System.Windows.Input;
   6: using BingMapsOData.Helpers;
   7: using BingMapsOData.ViewModels;
   8: using Microsoft.Maps.MapControl;
   9:  
  10: namespace BingMapsOData
  11: {
  12:     public partial class MainPage : UserControl
  13:     {
  14:         NerdDinnerViewModel vm;
  15:         MapSearchHelper searchHelper = new MapSearchHelper();
  16:         
  17:         public MainPage()
  18:         {
  19:             InitializeComponent();
  20:             InitializeViewModel();
  21:  
  22:             dinnerMap.TargetViewChanged += new EventHandler<MapEventArgs>(dinnerMap_TargetViewChanged);
  23:  
  24:             sldZoom.Value = dinnerMap.ZoomLevel;
  25:             sldZoom.ValueChanged += new RoutedPropertyChangedEventHandler<double>(ZoomChange);
  26:  
  27:             MiniMap.MouseClick += new EventHandler<MapMouseEventArgs>(MiniMap_MouseClick);
  28:             MiniMap.MouseDoubleClick += new EventHandler<MapMouseEventArgs>(MiniMap_MouseDoubleClick);
  29:             MiniMap.MouseDragBox += new EventHandler<MapMouseDragEventArgs>(MiniMap_MouseDragBox);
  30:             MiniMap.MousePan += new EventHandler<MapMouseDragEventArgs>(MiniMap_MousePan);
  31:             MiniMap.MouseWheel += new System.Windows.Input.MouseWheelEventHandler(MiniMap_MouseWheel);
  32:             MiniMap.KeyUp += new System.Windows.Input.KeyEventHandler(MiniMap_KeyUp);
  33:             MiniMap.KeyDown += new System.Windows.Input.KeyEventHandler(MiniMap_KeyDown);
  34:             MiniMap.KeyPress += new EventHandler<MapKeyPressEventArgs>(MiniMap_KeyPress);
  35:             MiniMap.KeyHeld += new EventHandler<MapKeyHeldEventArgs>(MiniMap_KeyHeld);
  36:             MiniMap.SetView(dinnerMap.TargetCenter, Math.Max(1.0, dinnerMap.TargetZoomLevel - 5));
  37:         }
  38:  
  39:         #region MainPage Events
  40:  
  41:         private void dinnerMap_TargetViewChanged(object sender, MapEventArgs e)
  42:         {
  43:             MiniMap.SetView(dinnerMap.TargetCenter, Math.Max(1.0, dinnerMap.TargetZoomLevel - 5));
  44:             sldZoom.Value = dinnerMap.TargetZoomLevel;
  45:         }
  46:  
  47:         #endregion
  48:  
  49:         #region MiniMap Events
  50:  
  51:         private void MiniMap_KeyHeld(object sender, MapKeyHeldEventArgs e)
  52:         {
  53:             e.Handled = true;
  54:         }
  55:  
  56:         private void MiniMap_KeyPress(object sender, MapKeyPressEventArgs e)
  57:         {
  58:             e.Handled = true;
  59:         }
  60:  
  61:         private void MiniMap_KeyDown(object sender, System.Windows.Input.KeyEventArgs e)
  62:         {
  63:             e.Handled = true;
  64:         }
  65:  
  66:         private void MiniMap_KeyUp(object sender, System.Windows.Input.KeyEventArgs e)
  67:         {
  68:             e.Handled = true;
  69:         }
  70:  
  71:         private void MiniMap_MouseWheel(object sender, System.Windows.Input.MouseWheelEventArgs e)
  72:         {
  73:             e.Handled = true;
  74:         }
  75:  
  76:         private void MiniMap_MousePan(object sender, MapMouseDragEventArgs e)
  77:         {
  78:             e.Handled = true;
  79:         }
  80:  
  81:         private void MiniMap_MouseDragBox(object sender, MapMouseDragEventArgs e)
  82:         {
  83:             e.Handled = true;
  84:         }
  85:  
  86:         private void MiniMap_MouseDoubleClick(object sender, MapMouseEventArgs e)
  87:         {
  88:             e.Handled = true;
  89:         }
  90:  
  91:         private void MiniMap_MouseClick(object sender, MapMouseEventArgs e)
  92:         {
  93:             e.Handled = true;
  94:         }
  95:  
  96:         #endregion
  97:  
  98:         #region Map Navigation
  99:  
 100:         private void ZoomChange(object sender, RoutedPropertyChangedEventArgs<double> e)
 101:         {
 102:             dinnerMap.ZoomLevel = sldZoom.Value;
 103:         }
 104:  
 105:         private void ZoomIn(object sender, MouseButtonEventArgs e)
 106:         {
 107:             dinnerMap.ZoomLevel = dinnerMap.TargetZoomLevel + 1;
 108:         }
 109:  
 110:         private void ZoomOut(object sender, MouseButtonEventArgs e)
 111:         {
 112:             dinnerMap.ZoomLevel = dinnerMap.TargetZoomLevel - 1;
 113:         }
 114:  
 115:         private void PanMapLeft(object sender, MouseButtonEventArgs e)
 116:         {
 117:             dinnerMap.Center = dinnerMap.ViewportPointToLocation(new Point(dinnerMap.ViewportSize.Width / 2 - 50, dinnerMap.ViewportSize.Height / 2));
 118:         }
 119:  
 120:         private void PanMapRight(object sender, MouseButtonEventArgs e)
 121:         {
 122:             dinnerMap.Center = dinnerMap.ViewportPointToLocation(new Point(dinnerMap.ViewportSize.Width / 2 + 50, dinnerMap.ViewportSize.Height / 2));
 123:         }
 124:  
 125:         private void PanMapUp(object sender, MouseButtonEventArgs e)
 126:         {
 127:             dinnerMap.Center = dinnerMap.ViewportPointToLocation(new Point(dinnerMap.ViewportSize.Width / 2, dinnerMap.ViewportSize.Height / 2 - 50));
 128:         }
 129:  
 130:         private void PanMapDown(object sender, MouseButtonEventArgs e)
 131:         {
 132:             dinnerMap.Center = dinnerMap.ViewportPointToLocation(new Point(dinnerMap.ViewportSize.Width / 2, dinnerMap.ViewportSize.Height / 2 + 50));
 133:         }
 134:  
 135:         private void MapStyleRoad(object sender, MouseButtonEventArgs e)
 136:         {
 137:             dinnerMap.Mode = new RoadMode();
 138:         }
 139:  
 140:         private void MapStyleAerial(object sender, MouseButtonEventArgs e)
 141:         {
 142:             dinnerMap.Mode = new AerialMode(false);
 143:         }
 144:  
 145:         private void MapStyleHybrid(object sender, MouseButtonEventArgs e)
 146:         {
 147:             dinnerMap.Mode = new AerialMode(true);
 148:         }
 149:  
 150:         #endregion
 151:  
 152:         /// <summary>
 153:         /// Initialize our view model, and assign it to the view
 154:         /// </summary>
 155:         private void InitializeViewModel()
 156:         {
 157:             vm = new NerdDinnerViewModel();
 158:             this.DataContext = vm;
 159:             try
 160:             {
 161:                 vm.QueryDinners();
 162:             }
 163:             catch (Exception ex)
 164:             {
 165:                 MessageBox.Show("Error loading the dinners. Make sure you are online. " + ex.Message);
 166:             }
 167:         }
 168:  
 169:         private void SearchDinners_Click(object sender, RoutedEventArgs e)
 170:         {
 171:             try
 172:             {
 173:                 if (!string.IsNullOrEmpty(txtPlace.Text))
 174:                     searchHelper.ExecuteSearch(txtPlace.Text, this.dinnerMap);
 175:             }
 176:             catch (Exception ex)
 177:             {
 178:                 MessageBox.Show("Error zooming in to " + txtPlace.Text + ex.Message);
 179:             }
 180:  
 181:             try
 182:             {
 183:                 vm.QueryDinners();
 184:             }
 185:             catch (Exception ex)
 186:             {
 187:                 MessageBox.Show("Error loading the dinners. Make sure you are online. " + ex.Message);
 188:             }
 189:         }
 190:     }
 191: }

Don’t forget to change the Bing Maps credentials in App.xaml with your own key. Hit F5 and your NerdDinner web application is ready to go!

Result

You can download the sample code in here. Enjoy…

Share this post: | | | |

Comments

No Comments