Been moving an application over from WPF Runtime to the new .Net...

4753
7
Jump to solution
12-19-2014 03:52 PM
BrianLocke
Occasional Contributor II

Did alot around MVVM and using MVVM Lite.  Liked how we could create a resource dictionary that would contain all of Layers.  From there, I was using the Interaction.Triggers and then depended on the Relay Command Bindings.  The problem is that Feature Services lack any mouse Handling events??  This makes it hard to subscribe to events within viewmodels???  I do see the hittestasync but scratching my head on how to go about getting the MapView touch/mouse events from the viewmodels.  Any suggestions? antti kajanus

Tags (3)
0 Kudos
1 Solution

Accepted Solutions
vincentvassallo
New Contributor III

MapViewTapped and MapViewDoubleTapped on the MapView are what you are looking for.

Code Example - MapView_Overlays‌ --- Example of MapViewTapped being used.

View solution in original post

7 Replies
vincentvassallo
New Contributor III

MapViewTapped and MapViewDoubleTapped on the MapView are what you are looking for.

Code Example - MapView_Overlays‌ --- Example of MapViewTapped being used.

View solution in original post

BrianLocke
Occasional Contributor II

Yeah I think that I have found a workaround..... all was going well and actually started to do a lot of moving.   so far found that the one of the best ways to interact with the Mapview is to just touch it in the codebehind..... goes against all of my MVVM (but who says you can't have some codebehind--use what works right:)_)  Also have events tied within codebehind too.  Now a big problem.  In the old WPF Runtime, when users moved the mouse over their map it would fire on the feature layer mouse over event, do lookup on attributed info, then report what Township range the users cursor was in.  Trying to replicate this behavior in the new Runtime and have this so far....

            //Screen Position needed for hit testing and the current Map Screen Point

            var screenPosition = e.GetPosition(WrmsMapView);

            #region Get the Lat and Long of the map and update the UI

            var latLongPosition = GeometryEngine.Project(WrmsMapView.ScreenToLocation(screenPosition),

                SpatialReferences.Wgs84);

            MouseCoordinates.UpdateLatLongHud(latLongPosition as MapPoint);

            #endregion

            var legalHudRows = await LegalHudFeatureLayer.HitTestAsync(WrmsMapView, screenPosition);

            if (legalHudRows != null && legalHudRows.Length > 0)

            {

                try

                {

                    var legalHudHitFeatures = await LegalHudFeatureLayer.FeatureTable.QueryAsync(legalHudRows);

                    returnedLegalFeature = legalHudHitFeatures.FirstOrDefault();

                    MouseCoordinates.UpdateLegalHud(returnedLegalFeature);

                }

                catch (Exception)

                {

                    MessageBox.Show(

                        "There was an error whike attempting to get the Rows Collection Attributed information");

                }

            }

Problem is that the mouse move events seem to be firing too fast.... get an instant crash within my application and Visual Studio doesn't even catch the exception.... really scratching my head on this one.... must admit also pretty curious.... why not just have Events on Feature Layers, Graphics, etc.??  I understand having succinct code but I feel that the events that existed with the WPF Runtime were extremely useful while applying MVVM 

I have also taken the time to look over the Runtime Examples and the map tapped events will be great for a lot of things and perhaps I need to go back to the drawing board on this problem.  Any suggestions ??

0 Kudos
BrianLocke
Occasional Contributor II

Got it, of course you were right.  I looked through the examples and found the key , you guys used _isMapReady Bool-- That did the trick.  Thanks

0 Kudos
vincentvassallo
New Contributor III

Glad I could help!

0 Kudos
BrianLocke
Occasional Contributor II

Thanks guys, as always you have put me back on the right path.

0 Kudos
AnttiKajanus1
Regular Contributor II

Happy new year and sorry for late response.

Depending on the use, MVVM style interaction between MapView - ViewModel can vary. But here are some ideas:

Requesting point from the map :

If you need to request point from the map you can either use Editor class directly from your ViewModel or you can use MapViewTapped event. Depending on the use case, either one can work very well. One way to define what to use is if you are "requesting a geometry" (use Editor) or you have "a continuous operation" like identify (MapViewTapped) but that's just an example. Sometimes you might have both going on the same time and one way to ignore MapViewTapped in this case is to check if Editor.IsActive and return if it is on MapViewTapped handler.

Other events / functions :

if you need to access MapView from ViewModel (ie. to use HitTest) you can follow "ViewServices"  concept. I shared a bit different implementation (but similar approach) on DevSummit 2014 that you can see from here. Both of these works well and doesn't violate MVVM pattern since there is no direct reference to the View in ViewModel. Please note that repo is not updated to latest.

- MapViewService : abstracts communication between ViewModel and MapView

- Sample how to use it.

Let me know if that helped at all.

dotMorten_esri
Esri Frequent Contributor

Wrt to "clicking a view going against MVVM": Clicking with a mouse on the view is a view operation. It belongs in the view code. These are view events that should stay in the view code (this is the prime example of where codebehind code is OK in MVVM). After the hittest is performed, you forward the feature that was hit to your viewmodel. You can also use a custom behavior to abstract it out a little more if you like, and have the feature that was hit be forwarded to your viewmodel.