2015-02-09 83 views
2

我试图为我的Windows 8.1程序实现一个地图屏幕,我正在使用Bing Maps API与C#和MVVM。Bing地图与C#和MVVM信息框和图钉绑定

我所面临的问题:

首先,我能够显示的图钉,并使用在XAML约束力,但是当我移动地图,信息框保持在相同的位置(在地图上的信息框以此为中心),而不是遵循图钉或地图运动。

这里的XAML:

<bm:Map ZoomLevel="15" Height="500" Width="600" ShowTraffic="False" ShowScaleBar="False" ShowNavigationBar="False" ShowBreadcrumb="False" ShowBuildings="False" 
      Credentials="xxxxxxx" Name="myMap" HorizontalAlignment="Stretch" VerticalAlignment="Stretch"> 
     <bm:Map.Center> 
      <bm:Location Latitude="-25.450520" Longitude="-49.251557" /> 
     </bm:Map.Center> 

     <bm:Map.Children> 

      <bm:MapLayer Name="DataLayer"> 
       <bm:Pushpin Style="{Binding PushpinStyle}"> 
        <bm:MapLayer.Position> 
         <bm:Location Latitude="{Binding Establishment.Pin.Latitude, Mode=OneWay}" Longitude="{Binding Establishment.Pin.Longitude, Mode=OneWay}" /> 
        </bm:MapLayer.Position> 
       </bm:Pushpin> 
      </bm:MapLayer> 

      <bm:MapLayer Margin="5,0,0,0" Position="{Binding InfoboxPosition}" Height="Auto" Width="Auto" > 
       <Grid x:Name="Infobox" Visibility="{Binding InfoboxVisibility}" Margin="35,0,0,0" Height="Auto" > 
        <Border MaxWidth="350" Style="{StaticResource InfoboxBorderStyle}" /> 
        <StackPanel Margin="10" MinWidth="200" MaxWidth="350"> 
         <Grid> 
          <TextBlock Text="{Binding Establishment.Name}" Style="{StaticResource InfoboxTitleStyle}" /> 
         </Grid> 
         <TextBlock Text="{Binding EstablishmentAddress}" Style="{StaticResource InfoboxContentStyle}" MaxWidth="290" Margin="7" /> 
        </StackPanel> 
       </Grid> 
      </bm:MapLayer> 

     </bm:Map.Children> 

    </bm:Map> 

其次,如果我有一个绑定列表上的多个图钉的地图,我怎么能添加“Pushpin.Tapped”事件为每个引脚调用的方法移动和设置从ViewModel可见的信息框? 目前我做它的工作使用简单的代码隐藏(不VM)有类似的东西:

public MapControl() 
    { 
     this.InitializeComponent(); 
     AddPushpin(new Location(-25.450520, -49.251557), "Title", "Description", DataLayer, EstablishmentKindEnum.Cinema); 
    } 

    private async void pushpinTapped(object sender, TappedRoutedEventArgs e) 
    { 
     Pushpin p = sender as Pushpin; 
     PushpinMetadata m = (PushpinMetadata)p.Tag; 

     //Ensure there is content to be displayed before modifying the infobox control 
     if (!String.IsNullOrEmpty(m.Title) || !String.IsNullOrEmpty(m.Description)) 
     { 
      Infobox.DataContext = m; 
      Infobox.Visibility = Visibility.Visible; 
      MapLayer.SetPosition(Infobox, MapLayer.GetPosition(p)); 
     } 
     else 
      Infobox.Visibility = Visibility.Collapsed; 
    } 

    private void CloseInfobox_Tapped(object sender, TappedRoutedEventArgs e) 
    { 
     Infobox.Visibility = Visibility.Collapsed; 
    } 

    public void AddPushpin(Location latlong, string title, string description, MapLayer layer, EstablishmentKindEnum kind) 
    { 
     var pushpin = MapHelper.CreatePushpin(latlong, title, description, kind); 
     MapLayer.SetPosition(pushpin, latlong); 
     pushpin.Tapped += pushpinTapped; 
     layer.Children.Add(pushpin); 
    } 

我需要从视图模型做这一切。 我是新的MVVM,任何人都可以给我一些提示?

回答

0

我一直在阅读关于MVVM的内容,有人说视图应该对所有的表示交互负责,ViewModel应该对数据负责。

我使其与下面的结构工作:

查看:

<Grid> 
    <bm:Map ZoomLevel="15" Height="500" Width="600" ShowTraffic="False" ShowScaleBar="False" ShowNavigationBar="False" ShowBreadcrumb="False" ShowBuildings="False" 
      Credentials="xxxxxx" Name="myMap" HorizontalAlignment="Stretch" VerticalAlignment="Stretch" DataContextChanged="Map_DataContextChanged"> 
     <bm:Map.Center> 
      <bm:Location Latitude="-25.450520" Longitude="-49.251557" /> 
     </bm:Map.Center> 

     <bm:Map.Children> 

      <bm:MapLayer Name="DataLayer"> 
       <bm:Pushpin Style="{Binding PushpinStyle}"> 
        <bm:MapLayer.Position> 
         <bm:Location Latitude="{Binding Establishment.Pin.Latitude, Mode=OneWay}" Longitude="{Binding Establishment.Pin.Longitude, Mode=OneWay}" /> 
        </bm:MapLayer.Position> 
       </bm:Pushpin> 
      </bm:MapLayer> 

      <bm:MapLayer Margin="5,0,0,0" Height="Auto" Width="Auto" > 
       <Grid x:Name="Infobox" Visibility="Collapsed" Margin="35,0,0,0" Height="Auto" > 
         <Border MaxWidth="350" Style="{StaticResource InfoboxBorderStyle}" /> 
        <StackPanel Margin="10" MinWidth="200" MaxWidth="350"> 
         <Grid> 
          <TextBlock Text="{Binding Establishment.Name}" Style="{StaticResource InfoboxTitleStyle}" /> 
          <Button Tapped="CloseInfobox_Tapped" Style="{StaticResource InfoboxCloseButtonStyle}" /> 
         </Grid> 
         <TextBlock Text="{Binding EstablishmentAddress}" Style="{StaticResource InfoboxContentStyle}" MaxWidth="290" Margin="7" /> 
        </StackPanel> 
       </Grid> 
      </bm:MapLayer> 

     </bm:Map.Children> 

    </bm:Map> 
</Grid> 

查看代码隐藏:

public sealed partial class MapControl : UserControl 
{ 
    public MapControl() 
    { 
     this.InitializeComponent(); 
    } 

    private async void pushpinTapped(object sender, TappedRoutedEventArgs e) 
    { 
     Pushpin p = sender as Pushpin; 
     Infobox.Visibility = Visibility.Visible; 
     MapLayer.SetPosition(Infobox, MapLayer.GetPosition(p)); 
    } 

    private void CloseInfobox_Tapped(object sender, TappedRoutedEventArgs e) 
    { 
     Infobox.Visibility = Visibility.Collapsed; 
    } 

    private void Map_DataContextChanged(FrameworkElement sender, DataContextChangedEventArgs args) 
    { 
     if (DataLayer.Children != null) 
      foreach (var pin in DataLayer.Children) 
      { 
       pin.Tapped += pushpinTapped; 
      } 
    } 
} 

我隐藏事件 “Pushpin.Tapped” 添加到所有引脚DataSource更改后的“DataLayer”,并控制Infobox的位置和可视性。 我认为这不是一个突破性的方法,如果你们有任何建议或意见,我会很高兴听到它。