在 Windows Phone 8 上以自定义方式将多个推送图钉添加到地图





5.00/5 (5投票s)
在本技巧中,我们将讨论一种快速方法,介绍如何定位地图中的点,然后通过示例 XML 将自定义图钉添加到这些位置。
引言
在本技巧中,我们将讨论一种快速方法,介绍如何定位地图中的点,然后通过示例 XML 将自定义图钉添加到这些位置。
背景
之前,我正在为一个 Windows Phone 应用程序工作,该应用程序需要在图钉上显示位置数据,并且要求显示来自 Web 服务器的多个位置。不幸的是,没有 Web API 可以从服务器获取 XML 文件来实现这种功能。因此,在本技巧中,我们将尝试快速浏览一下如何定位地图中的点,然后通过示例 XML 将自定义图钉添加到这些位置。
在地图上定位一个点或地址,并在该固定点上指定更多信息,无论您是否缩放它。这些固定点称为图钉。
这些图钉可用于显示该位置更精确的信息。 例如,我们有 Google India,班加罗尔位置,对于此,图钉可用于简单地在地图上指向位置,或者当您点击该图钉时,它也可以指定地址。
通过此示例应用程序,我们将了解如何在地图上显示具有多个图钉位置的图钉。 此外,我们将尝试自定义图钉的设计,同时点击以查看其内容。
Using the Code
让我们看一下示例应用程序,以在地图控件上显示多个图钉。 我尝试以 MVVM 方式实现此功能,但是整个代码并非以这种方式编写。 由于我没有为命令绑定编写代码,或者可以使用PRISM在单个库中获取所有这些功能,因此我将在以后的版本中尝试使其正常工作。
让我们继续创建一个新的 Windows Phone 项目。

现在选择操作系统版本为 Windows Phone OS 8.0。

为了使用 MVVM,我在解决方案中添加了 *Model*,*View* 和 *ViewModel* 文件夹。

现在让我们为应用程序的启动页面编写代码。 这是 XAML,即我们将在屏幕上看到的 UI
<Grid x:Name="LayoutRoot" Background="Transparent">
    <Grid.RowDefinitions>
            <RowDefinition Height="Auto"/>
            <RowDefinition Height="*"/>
        </Grid.RowDefinitions>       
        <StackPanel x:Name="TitlePanel" 
        Grid.Row="0" Margin="12,17,0,28">
            <TextBlock Text="Sample Pushpin App" 
              Style="{StaticResource PhoneTextNormalStyle}" Margin="12,0"/>
 <TextBlock Text="Google India" Margin="9,-7,0,0" 
    Style="{StaticResource  PhoneTextTitle1Style}"/>
        </StackPanel>
        <Grid x:Name="ContentPanel" Grid.Row="1" Margin="12,0,12,0">
            <Button Content="Show Map" 
            Height="140" Click="Button_Click"></Button>
        </Grid>
</Grid>
我们这里有一个按钮可以切换到地图视图。 现在,在按钮单击时,我们将导航到另一个页面,在其中我们将看到地图视图。
private void Button_Click(object sender, RoutedEventArgs e)
{
    (Application.Current.RootVisual as PhoneApplicationFrame).Navigate(
               new Uri("/View/MapView.xaml", UriKind.Relative));
}

现在,在我们开始进行编码之前,您需要获取在 Windows Phone 应用程序中使用地图的凭据。 要了解如何获取凭据,请参阅此链接。如果您没有获得凭据,那么您可能会感到恼火,因为地图上会不断出现一条白色条带,敦促您获取凭据以使用地图控件。
<phone:PhoneApplicationPage.Resources>
    <DataTemplate x:Key="PinItemTemplate">
        <local:Pushpin  Background="Red" 
        Location="{Binding Location}" Tap="PushpinTap">
            <local:Pushpin.Content>
                <StackPanel Name="PushpinStack" Visibility="Collapsed">
                    <TextBlock Text="{Binding ID}" Visibility="Collapsed" />
                    <Border Background="Black" HorizontalAlignment="Center" >
                        <Grid>
                            <Grid.RowDefinitions>
                                <RowDefinition Height="Auto"/>
                                <RowDefinition Height="Auto"/>
                            </Grid.RowDefinitions>
                            <Grid.ColumnDefinitions>
                                <ColumnDefinition Width="Auto"/>
                                <ColumnDefinition Width="Auto"/>
                            </Grid.ColumnDefinitions>
                            <TextBlock  Text="{Binding ADDRESS}" 
                                   Grid.Row="0" Grid.Column="0" Margin="5,5,5,0"/>
                            <StackPanel Grid.Row="1" 
                                   Grid.Column="0" Orientation="Horizontal">
                                <TextBlock Text="{Binding CITY}" Margin="5,0,5,5" />
                                <TextBlock Text="{Binding STATE}" Margin="5,0,5,5" />
                                <TextBlock Text="{Binding ZIP}" Margin="5,0,5,5" />
                            </StackPanel>
                        </Grid>
                    </Border>
                </StackPanel>
            </local:Pushpin.Content>
        </local:Pushpin>
    </DataTemplate>
</phone:PhoneApplicationPage.Resources>
<Grid x:Name="LayoutRoot">
    <phone:Pivot>
        <phone:PivotItem>
            <phone:PivotItem.Header>
                <TextBlock Text="Map Us"></TextBlock>
            </phone:PivotItem.Header>
            <Grid>
                <Grid.RowDefinitions>
                    <RowDefinition Height="*"/>
                </Grid.RowDefinitions>
                <StackPanel Grid.Row="0" Opacity="0.7">
                    <StackPanel.Background>
                        <LinearGradientBrush EndPoint="0.5,1" StartPoint="0.5,0">
                            <GradientStop Color="Black" Offset="0"/>
                            <GradientStop Color="#FF424242" Offset="1"/>
                        </LinearGradientBrush>
                    </StackPanel.Background>                                    
                </StackPanel>
                <local:Map Center="{Binding CurrentLocation}" Tap="map_Tap_1"
                  Name="map" Grid.Row="1" CopyrightVisibility="Collapsed" 
                  LogoVisibility="Collapsed" Foreground="Red"                   
                ZoomLevel="7"
                CredentialsProvider="type your credential here"
                HorizontalAlignment="Stretch"
                VerticalAlignment="Stretch">
                    <local:MapItemsControl x:Name="MapPins"
            ItemsSource="{Binding GetLocationData}"
            ItemTemplate="{StaticResource PinItemTemplate}"
            />
                </local:Map>
            </Grid>
        </phone:PivotItem>
    </phone:Pivot>
</Grid> 
当您需要对特定图钉执行更具体的操作时,此函数很有用。
我编写此函数是为了获取用户点击的图钉。 由于我们这里有 5 个图钉,并且我需要找到用户点击的特定图钉,因此我在点击图钉时需要进行更多操作。
private T GetChild<T>
(DependencyObject obj, int selectedindex) where T : DependencyObject
{
    DependencyObject child = null;
    for (Int32 i = 0; i < VisualTreeHelper.GetChildrenCount(obj); i++)
    {
        child = VisualTreeHelper.GetChild(obj, i);
        if (child != null && child.GetType() == typeof(T))
        {
            if (i == selectedindex)
                break;
        }
        else if (child != null)
        {
            child = GetChild<T>(child, selectedindex);
            if (child != null && child.GetType() == typeof(T))
            {
                if (i == selectedindex)
                    break;
            }
        }
    }
    return child as T;
}

您可以在 *Helper* 文件夹中找到一个函数,用于解析类型为 T 的 XML,该函数实际上将解析我们的 *location.xml* 并将其映射到我们的模型。
public static T Deserialize<T>(string xml)
{
    try
    {
        using (var stream = new MemoryStream(Encoding.Unicode.GetBytes(xml)))
        {
            XmlSerializer serializer = new XmlSerializer(typeof(T));
            XDocument document = XDocument.Parse(xml);
            T theObject = (T)serializer.Deserialize(document.CreateReader());
            return theObject;
        }
    }
    catch (Exception ex)
    {
        throw ex;
    } 
}
在点击图钉时,用户将能够查看图钉的内容。 您可以为这些图钉弹出窗口提供更多自定义设计。
private void PushpinTap(object sender, GestureEventArgs e)
{
    Pushpin pushpin = sender as Pushpin;
    if (pushpin.Content != null)
    {
        StackPanel content = (StackPanel)pushpin.Content;
        if (content.Visibility == Visibility.Collapsed)
        {
            content.Visibility = Visibility.Visible;
        }
    }
    // to stop the event from going to the parent map control
    e.Handled = true;
}

地图点击功能实际上将折叠所有显示内容的打开的图钉。
private void map_Tap_1(object sender, GestureEventArgs e)
{
    int count = MapPins.Items.Count;
    for (int i = 0; i <= count; i++)
    {
        DependencyObject obj = GetChild<Pushpin>(MapPins, i);
        if (obj != null)
        {
            Pushpin pin = obj as Pushpin;
            StackPanel sb = pin.FindName("PushpinStack") as StackPanel;
            if (sb != null)
            {
                sb.Visibility = System.Windows.Visibility.Collapsed;
            }
        }
    }
} 

关注点
我们在这里看到了如何从 XML 文件实现多个图钉。
如果人们调用某种 Web API,并且可以使用某些 Web 客户端下载此 XML 并进行解析以在 UI 上表示,则人们也可以从服务器获取此 XML 文件。
我希望此技巧足以解释在地图上动态图钉的实现以及我们如何自定义图钉视图。
注意:本文的示例代码已在 VS 2012 中编写,并且我使用了可以在 Windows 8 操作系统上安装的 Windows Phone SDK 8.0。 因此,要运行此代码,您必须具有 Visual Studio 2012 和 Windows Phone 的 SDK 8.0。
历史
- 2013 年 10 月 3 日:第一个版本


