正如在評論中提到的,最好的辦法是綁定圖釘集合。
Bing地圖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}"/>
而且你有它。
MVVM純粹主義者在視圖中沒有代碼。你只綁定到你的ViewModel,它有你的模型提供的點集合。 – SQLMason
您的ViewModel不必對您的視圖一無所知。這是MVVM打破。正如@丹安德魯斯所說,你必須在視圖模型(或模型)上創建一個映射,並將其綁定到你的視圖。 – Jose
而不是'EventToCommand',你可以創建附加的行爲(使用幾個附加的屬性)。在該行爲的代碼中,您可以訪問所有內容:雙擊事件(訂閱它),映射(將其作爲附加屬性傳遞)和ViewModel(元素的DataContext或將它作爲另一個附加屬性傳遞)。 – Sinatr