c# - Bing map 与 C# 和 MVVM 信息框和图钉绑定(bind)

标签 c# wpf mvvm windows-store-apps bing-maps

我正在尝试为我的 Windows 8.1 程序实现 map 屏幕,我正在使用 Bing Maps API 与 C# 和 MVVM。

我遇到的问题:

首先,我可以在 xaml 中使用绑定(bind)在 map 上显示图钉和信息框,但是当我移动 map 时,信息框保持在相同位置(在这种情况下居中),而不是跟随图钉或 map 移动。

这里是 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>

其次,如果我的 map 在列表上绑定(bind)了多个图钉,我如何为每个图钉添加“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);
    }

我需要通过 ViewModel 来完成这一切。 我是 MVVM 的新手,有人可以给我一些提示吗?

最佳答案

我一直在阅读有关 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>

查看代码隐藏:

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”中的所有图钉,并且还控制信息框的位置和可见性。 我认为这不是一种打破模式的方法,如果你们有任何建议或意见,我会很高兴听到。

关于c# - Bing map 与 C# 和 MVVM 信息框和图钉绑定(bind),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/28408621/

相关文章:

c# - C# WPF 中奇怪的换行行为

c# - WPF MVVM 应用程序中的启动画面

c# - 如何限制物体旋转到一定程度?

C#/ASP.NET : can't remove cookies with Domain property specified

c# - 如何保存和使用应用程序的窗口大小?

c# - 处理 Prism 4 模块中的异常

.net - Silverlight+MVVM-Light 中的 SelectionChanged 事件绑定(bind)

c# - MVVM ViewModel 级联属性

c# - 在 Quartz.net 中,如何在使用单个 IJob 时防止作业同时运行?

c# - 从父类的实例创建派生类的实例