2015-02-09 2 views
2

Я пытаюсь реализовать экран карты для моей программы Windows 8.1, и я использую Bing Maps API с C# и MVVM.Bing Maps с C# и MVVM Infobox и pushpin Bindings

Проблемы я сталкиваюсь:

Во-первых, я могу показать булавку и инфобокс на карте, используя привязки в 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? В настоящее время я сделать его работу с помощью простого CodeBehind (не 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); 
    } 

мне нужно сделать все это из ViewModel. Я новичок в MVVM, кто-нибудь может дать мне несколько советов?

ответ

0

Я читал о MVVM, и некоторые люди говорят, что View должен нести ответственность за все взаимодействия презентации, и 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> 

Просмотр CodeBehind:

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" для всех выводов в «DataLayer» после изменения DataSource, а также контролирует положение и видимость Infobox. Я думаю, что это не шаблонный подход, и если у вас есть какие-либо предложения или комментарии, я буду рад это услышать.

Смежные вопросы