我正在尝试正确使用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的参数。
答案 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}"/>
你有它。