MVVM - 将点添加到地图

时间:2015-11-03 14:00:55

标签: c# wpf mvvm

我正在尝试正确使用MVVM模式。

因此,在这个例子中,我尝试使用MVVM模型向地图添加一些点。最好的方法是什么?

查看:

<map:Map Name="MyMap">
        <i:Interaction.Triggers>
            <i:EventTrigger EventName="MouseDoubleClick">
                <cmd:EventToCommand Command="{Binding DoubleClickCommand}"
                                    EventArgsConverter="{StaticResource ConvertToPoint}"
                                    PassEventArgsToCommand="True" />
            </i:EventTrigger>
        </i:Interaction.Triggers>
        <map:MapLayer Name="MyLayer">

        </map:MapLayer>
    </map:Map>

视图模型:

public class MainWindowViewModel: ViewModelBase
{
    public RelayCommand<Point> DoubleClickCommand { get; private set; }

    public MainWindowViewModel()
    {
        this.DoubleClickCommand = new RelayCommand<Point>(CreatePoint);
    }

    private void CreatePoint(Point arg)
    {
        Ellipse pin = new Ellipse();
        pin.Width = 3;
        pin.Height = 3;
        pin.Fill = Brushes.Blue;

        Point point = arg;
        Location PointLocation = MyMap.ViewportPointToLocation(point);

        MyLayer.AddChild(pin, PointLocation);
    }
}

以下两行都有问题,因为它使用了视图的控件:

  

位置PointLocation = MyMap.ViewportPointToLocation(point);

  

MyLayer.AddChild(pin,PointLocation);

我在哪里写这些?在视图背后的代码中?

备注:我使用转换器获取一个点作为函数CreatePoint的参数。

1 个答案:

答案 0 :(得分:0)

正如评论中所提到的,最好的方法是绑定到图钉集合。

Bing Maps WPF控件Binding方面不是很宽容。无法直接绑定到地图的Children属性,因此需要采用不同的方法。

首先,创建一个包含地图的UserControl,然后我们可以使用依赖属性Children执行几乎代理绑定集合。

<UserControl ...
         xmlns:m="clr-namespace:Microsoft.Maps.MapControl.WPF;assembly=Microsoft.Maps.MapControl.WPF"">
<Grid>
    <m:Map CredentialsProvider="Your API Key Here"
           x:Name="map"
           MouseDoubleClick="Map_DoubleClicked"/>
</Grid>

以下是代码隐藏:

public partial class BindableMap : UserControl
{
    public ObservableCollection<Pushpin> Pins
    {
        get { return (ObservableCollection<Pushpin>)GetValue(PinsProperty); }
        set { SetValue(PinsProperty, value); }
    }

    // Using a DependencyProperty as the backing store for Pins.  This enables animation, styling, binding, etc...
    public static readonly DependencyProperty PinsProperty =
        DependencyProperty.Register("Pins", typeof(ObservableCollection<Pushpin>), typeof(BindableMap),
        new PropertyMetadata(null, new PropertyChangedCallback(OnPinsChanged)));

    private static void OnPinsChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
    {
        BindableMap map = (BindableMap)d;

        //If the pin collection changes, then reset the map view.
        map.ClearMapPoints();
        map.SubscribeToCollectionChanged();
    }

    private void ClearMapPoints()
    {
        map.Children.Clear();
    }

    private void SubscribeToCollectionChanged()
    {
        if (Pins != null)
            Pins.CollectionChanged += Pins_CollectionChanged;
    }

    private void Pins_CollectionChanged(object sender, System.Collections.Specialized.NotifyCollectionChangedEventArgs e)
    {
        //Remove the old pushpins
        if (e.OldItems != null)
            foreach (Pushpin pin in e.OldItems)
                map.Children.Remove(pin);

        //Add the new pushpins
        if (e.NewItems != null)
            foreach (Pushpin pin in e.NewItems)
                map.Children.Add(pin);
    }

    public BindableMap()
    {
        InitializeComponent();

        Pins = new ObservableCollection<Pushpin>();
    }

    private void Map_DoubleClicked(object sender, MouseButtonEventArgs e)
    {
        //Get the current position of the mouse.
        Point point = Mouse.GetPosition(map);

        //Create the pin.
        Pushpin pin = new Pushpin();
        pin.Location = map.ViewportPointToLocation(point);

        //Add the pin to the map.
        Pins.Add(pin);
    }
}

这里需要注意的是View,在这种情况下,UserControl正在处理双击事件。这不一定需要在视图模型中处理,因为我们将改为使用绑定。

这是一个非常简单的视图模型:

public class BindableMapViewModel : PropertyChangedBase
{
    private ObservableCollection<Pushpin> _Pushpins;

    public ObservableCollection<Pushpin> Pushpins
    {
        get { return _Pushpins; }
        set
        {
            _Pushpins = value;
            NotifyOfPropertyChange();
        }
    }

    public BindableMapViewModel()
    {
        Pushpins = new ObservableCollection<Pushpin>();
    }
}

现在,剩下的就是在父UserControl中使用Window并将Pushpins视图模型集合绑定到Pins 依赖项属性。它看起来像这样:

<map:BindableMap Pins="{Binding Pushpins}"/>

你有它。