Select to view content in your preferred language

Drag and Drop onto Map

2451
13
Jump to solution
01-22-2014 11:23 AM
Labels (1)
KeithGemeinhart
Regular Contributor
I'm looking for advice on implementing drag & drop onto the WPF map control. My goal is to drag from a list of items, and drop on the map to create a new graphic/feature at the drop location.

The map has Drop and PreviewDrop events, but neither provide the map/mouse coordinates of the drop event. Am I missing something in the events? Both have DragEventArgs as the parameter.

All I really need is the mouse's map position when the drop happens. With that in mind, I also tried to get mouse move events, but they don't seem to carry any position either, only MouseEventArgs.

Any ideas? Am I missing something obvious?

Thanks!

P.S. ArcGIS Runtime 10.1.1, but I can upgrade to 10.2 if there is something that will help.
0 Kudos
1 Solution

Accepted Solutions
KeithGemeinhart
Regular Contributor
Here is a sample project that you download: https://github.com/keithgemeinhart/ArcGis.Wpf.DragDropDemo

A couple of key points ....

I use the GalaSoft MVVM Light library to get an implementation of EventToCommand. The provides a mechanism for mapping an event to a command in the view model. For example:

<i:Interaction.Triggers >    <i:EventTrigger EventName="Loaded">     <cmd:EventToCommand Command="{Binding MapLoadedCommand, Source={StaticResource DragDropViewModel}}" PassEventArgsToCommand="True"/>    </i:EventTrigger> </i:Interaction.Triggers>


This maps the Loaded event on the map to the MapLoadedCommand in the DragDropViewModel. That's a key event because we need a means for getting a map reference into the view model. So my solution was to capture the map reference as a parameter of the map's Loaded event. Here is the implementation in the view model. The last line in the method extracts the map reference from the RoutedEventArgs Source property.

private void MapLoaded(object parameter) {     // See if the event sent the map in the event args     var p1 = parameter as System.Windows.RoutedEventArgs;     if (p1 == null)     {         throw new NullReferenceException("Cannot capture map reference.");         return;     }      _map = p1.Source as Map; }


If you have any questions, just let me know.

View solution in original post

0 Kudos
13 Replies
BjørnarSundsbø
Deactivated User
Have you tried getting the mouse position relative to the map, and then using ScreenToMap to get the map location, when in the drop event?

var mousePosition = Mouse.GetPosition(PART_Map);
var mapPoint = PART_Map.ScreenToMap(mousePosition);
0 Kudos
KeithGemeinhart
Regular Contributor
How do I get to PART_Map?

Have you tried getting the mouse position relative to the map, and then using ScreenToMap to get the map location, when in the drop event?

var mousePosition = Mouse.GetPosition(PART_Map);
var mapPoint = PART_Map.ScreenToMap(mousePosition);
0 Kudos
BjørnarSundsbø
Deactivated User
How do I get to PART_Map?


Sorry about the confusion. PART_Map is the Map control itself.
0 Kudos
KeithGemeinhart
Regular Contributor
Thanks! It's kind of working, but I think there might be a problem with offset or projection because my coordinates are not right.

Here is what I get when adding using the Editor method. This is the correct point ...
Point[X=-10729734.0395236, Y=5233362.65677612, WKID=102100]

These are the values I'm getting with the method described above for the same point ...
Point[X=-12276503.6815948, Y=6334347.01772725, WKID=102100]

Any thoughts or suggestions?
0 Kudos
KeithGemeinhart
Regular Contributor
Still looking for a solution for this. I also added the following lines without any real effect:
            if (_map.WrapAroundIsActive)
                mapPoint = Geometry.NormalizeCentralMeridian(mapPoint) as MapPoint;
0 Kudos
AnttiKajanus1
Deactivated User
One thing that could affect this (cant remember what versions of the SDK this was an issue) is that if your map is not full screen ie. you have another element on left/top of the map? If so, then the point could be that many pixels in wrong place.
0 Kudos
KeithGemeinhart
Regular Contributor
Interesting ... After testing this a little more, it appears that the drops are accumulating at what would be the top, left corner of the screen. If I drop in multiple locations, they all stack in that same spot.

Any advice on how to correct the offset? Should I be looking at some combination of the window's upper, left corner and map's upper, left corner? Or is there more to it than that?

Has it been corrected in 10.2?

Thanks!


One thing that could affect this (cant remember what versions of the SDK this was an issue) is that if your map is not full screen ie. you have another element on left/top of the map? If so, then the point could be that many pixels in wrong place.
0 Kudos
KeithGemeinhart
Regular Contributor
Did another test, and this line always returns the upper, left corner of the map control with respect to the screen, but in negative numbers. So if the map control is positioned at 100, 100 on the screen, then Mouse.GetPosition would return -100, -100.

The same value is returned regardless of where I drop on the map.

var mousePosition = Mouse.GetPosition(_map);
0 Kudos
KeithGemeinhart
Regular Contributor
Persistence pays off. The problem was the call to Mouse.GetPosition. It should be DragEventArgs.GetPosition. Here is the complete solution:


        private void Drop(object e)
        {
            var args = e as DragEventArgs;
            if (args == null)
                return;

            var mousePosition = args.GetPosition(_map);
            var mapPoint = _map.ScreenToMap(mousePosition);

            if (_map.WrapAroundIsActive)
                mapPoint = Geometry.NormalizeCentralMeridian(mapPoint) as MapPoint;

            var graphic = new Graphic();
            graphic .Geometry = mapPoint;

            MyLayer.Graphics.Add(graphic );
        }


I have this wired-up using a Command & ViewModel. I can post that part if anyone is interested, just let me know.
0 Kudos