Binden Xamarin.Formen.Maps.Karte von ViewModel
Arbeite ich an einer Xamarin.Forms-Anwendung mit einer Seite, die zeigt eine Karte.
Der XAML-Code ist:
<maps:Map x:Name="Map">
...
</maps:Map>
Ich weiß, dass die Karte zugegriffen werden kann, von der Seite code-behind-so:
var position = new Position(37.79762, -122.40181);
Map.MoveToRegion(new MapSpan(position, 0.01, 0.01));
Map.Pins.Add(new Pin
{
Label = "Xamarin",
Position = position
});
Aber da dieser code brechen würde die app MVVM-Architektur, ich würde lieber Zugriff auf die Map
Objekt aus meinem ViewModel, nicht direkt aus der Sicht/Seite - entweder über direkt wie im obigen code oder per databinding auf seine Eigenschaften.
Weiß jemand einen Weg, wie dies geschehen kann?
Du musst angemeldet sein, um einen Kommentar abzugeben.
Wenn Sie nicht wollen, zu brechen, das MVVM-Muster und immer noch Zugriff auf Ihre Map-Objekt aus dem ViewModel, dann können Sie aussetzen des Map-Instanz mit einer Eigenschaft aus der ViewModel binden und es aus Ihrer Sicht.
Ihr code sollte strukturiert werden, wie hier beschrieben, unten.
ViewModel:
View (in diesem Beispiel verwende ich ein
ContentPage
aber Sie können verwenden, was Ihnen gefällt):Ich zeigen nicht, wie, aber der obige code snipped kann nur funktionieren, wenn das ViewModel ist die
BindingContext
Ihrer Ansicht.Habe ich zwei Optionen die für mich gearbeitet hat und was Ihnen helfen könnte.
Können Sie entweder fügen Sie eine statische
Xamarin.Forms.Maps Map
Eigenschaft, um IhreViewModel
und setzen diese statische Eigenschaft nach der Einstellung der verbindliche Kontext, während der Instanzierung der View, wie unten dargestellt:Diese erlauben Ihnen den Zugang zu Ihren Anzeigen in der ViewModel.
Könnten Sie übergeben Sie Ihre Karte von Ihrem view-ViewModel während die Bindung, zum Beispiel:
Und Holen Sie sich die Karte hinter der ViewModel-Befehl.
Was zum erstellen einer neuen Control-sagen
BindableMap
was erbt von Map und führt die binding-updates, die die ursprünglicheMap
fehlt intern. Die Umsetzung ist ziemlich einfach und ich habe 2 grundlegende Anforderungen; dasPins
- Eigenschaft und die aktuellenMapSpan
. Natürlich können Sie fügen Sie Ihre eigenen speziellen Bedürfnisse zu dieser Steuerung. Alles, was Sie danach tun ist, um eine Eigenschaft vom TypObservableCollection<Pin>
zu Ihrem ViewModel und binden Sie es an die PinsSource Eigentum IhrerBindableMap
in XAML.Hier ist die BindableMap:
Hinweise:
Pins
- Eigenschaft aktualisiert werden fügen wir die Mitglieder unseres bindbarePinsSource
Eigenschaft, erklärte ich derPinsSource
alsObservableCollection<Pin>
und abonniert seinenCollectionChanged
Veranstaltung. Natürlich können Sie definieren es als eineIList
wenn Sie wollen, ändern Sie nur die gesamte Wert Ihrer gebundenen Eigenschaft.Meine Letzte Wort über die 2 ersten Antworten zu dieser Frage:
Obwohl Sie ein View-Steuerelement als eine ViewModel-Eigenschaft befreit uns von dem schreiben der business-Logik im code dahinter, aber es fühlt sich immer noch eine Art hacky. Meiner Meinung nach, der springende Punkt, der (naja, zumindest einen wichtigen Punkt im) der VM Teil des MVVM ist, dass es völlig getrennt und entkoppelt von der V. in der Erwägung, dass die Lösung in den oben genannten Antworten ist eigentlich diese:
Ich denke, dass dieser Weg, nicht nur brechen Sie das MVVM-Muster, aber auch Sie bricht Ihr Herz!
INotifyPropertyChanged
, und hat IhrIList<Pin>
Eigentum nennenNotifyPropertyChanged()
in seinerset
Abschnitt?Ich glaube nicht, dass
Pins
ist eine bindbare Eigenschaft aufMap
, möchten Sie vielleicht, um die Datei feature-request an Xamarin ist Uservoice oder das fourm hier: http://forums.xamarin.com/discussion/31273/Es ist nicht ideal, aber man konnte hören, die für das property changed-Ereignis in der code-behind und dann übernehmen Sie die änderung, von dort aus. Es ist ein bisschen Anleitung, aber es ist machbar.
Und definieren Sie dann die "yourPropertyChanged" Methode