Mouse Coords Addin not working

2858
6
Jump to solution
07-20-2012 08:47 AM
CMICNRE
New Contributor II
I'm trying to convert the an Interactive SDK mouse coordinates sample to a Viewer Addin, and I want to control the coordinates panel with a toolbar button.  My tool opens the window and shows the usercontrol, but the coordinates are blank.  I'm not sure if I have the map binding wrong or the MouseMouse event isn't firing.  I'm new to Silverlight and normally code in VB, so any help is appreciated.

Here is my UserControl MouseCoords.xaml:

<UserControl x:Class="Mapper.AddIns.MouseCoords"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
    xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
             xmlns:esriExt="http://schemas.esri.com/arcgis/client/extensibility/2010"
    mc:Ignorable="d"
    d:DesignHeight="300" d:DesignWidth="400">

    <Grid x:Name="LayoutRoot" Background="White">
        <Grid Width="355" Height="65" HorizontalAlignment="Right" VerticalAlignment="Top" Margin="0,15,15,0" >
            <Rectangle Stroke="Gray"  RadiusX="10" RadiusY="10" Fill="#77919191" Margin="0,0,0,6" >
                <Rectangle.Effect>
                    <DropShadowEffect/>
                </Rectangle.Effect>
            </Rectangle>
            <Rectangle Fill="#FFFFFFFF" Stroke="DarkGray" RadiusX="5" RadiusY="5" Margin="10,10,10,15"  />
            <StackPanel Canvas.Left="20" Canvas.Top="14" Margin="20,14,10,0">
                <TextBlock x:Name="ScreenCoordsTextBlock"
                    HorizontalAlignment="Left" VerticalAlignment="Center" Text="Screen Coords: " TextWrapping="Wrap" FontWeight="Bold" />
                <TextBlock x:Name="MapCoordsTextBlock"
                    HorizontalAlignment="Left" VerticalAlignment="Center" Text="Map Coords: " TextWrapping="Wrap" FontWeight="Bold" />
            </StackPanel>
        </Grid>

    </Grid>
</UserControl>

User control code-behind MouseCoord.xaml.cs:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Windows.Shapes;
using ESRI.ArcGIS.Client.Extensibility;
using ESRI.ArcGIS.Client;

namespace Mapper.AddIns
{
    public partial class MouseCoords : UserControl
    {
        public MouseCoords()
        {
            InitializeComponent();
        }

        public Map MyMap
        {
            get { return MapApplication.Current.Map; }
        }

        private void MyMap_MouseMove(object sender, System.Windows.Input.MouseEventArgs args)
        {
            if (MyMap.Extent != null)
            {
                System.Windows.Point screenPoint = args.GetPosition(MyMap);
                ScreenCoordsTextBlock.Text = string.Format("Screen Coords: X = {0}, Y = {1}",
                    screenPoint.X, screenPoint.Y);

                ESRI.ArcGIS.Client.Geometry.MapPoint mapPoint = MyMap.ScreenToMap(screenPoint);
                if (MyMap.WrapAroundIsActive)
                    mapPoint = ESRI.ArcGIS.Client.Geometry.Geometry.NormalizeCentralMeridian(mapPoint) as ESRI.ArcGIS.Client.Geometry.MapPoint;
                MapCoordsTextBlock.Text = string.Format("Map Coords: X = {0}, Y = {1}",
                    Math.Round(mapPoint.X, 4), Math.Round(mapPoint.Y, 4));
            }
        }
    }
}

Here is the tool ShowMouseCoordinatesTool.cs:

using System;
using System.Net;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;
using System.Windows.Ink;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Windows.Shapes;
using ESRI.ArcGIS.Client;
using ESRI.ArcGIS.Client.Extensibility;
using ESRI.ArcGIS.Client.Application.Controls;
using System.ComponentModel;
using System.ComponentModel.Composition;

namespace Mapper.AddIns
{
    [Export(typeof(ICommand))]
    [DisplayName("Map Coordinates")]
    [ESRI.ArcGIS.Client.Extensibility.Category("UTC Tools")]
    [ESRI.ArcGIS.Client.Extensibility.Description("Display mouse coordinates in map units")]
    public class ShowMouseCoordsTool : ICommand
    {
        private MouseCoords coords = new MouseCoords();
        private MyConfigDialog configDialog = new MyConfigDialog();

        #region ICommand members
        public void Execute(object parameter)
        {
            MapApplication.Current.ShowWindow("Map Coordinates", coords);
        }

        public bool CanExecute(object parameter)
        {
            // Return true so that the command can always be executed
            return true;
        }

        public event EventHandler CanExecuteChanged;

        #endregion
    }
}
0 Kudos
1 Solution

Accepted Solutions
ScottFriedrich
New Contributor III
Laura,

I was able to display the mouse coordinates using a Behavior.  I implemented a behavior because I always want the coordinates to display and do not want to turn them off. 

First I added to the xaml of the Layout I am using the following:


<Grid Width="355" Height="65" HorizontalAlignment="Right" VerticalAlignment="Top" Margin="0,50,15,0" >             <Rectangle Stroke="Gray"  RadiusX="10" RadiusY="10" Fill="#77919191" Margin="0,0,0,6" >                 <Rectangle.Effect>                     <DropShadowEffect/>                 </Rectangle.Effect>             </Rectangle>             <Rectangle Fill="#FFFFFFFF" Stroke="DarkGray" RadiusX="5" RadiusY="5" Margin="10,10,10,15"  />             <StackPanel Canvas.Left="20" Canvas.Top="14" Margin="20,14,10,0">                                 <TextBlock x:Name="MapCoordsTextBlock"                      HorizontalAlignment="Left" VerticalAlignment="Center" Text="Map Coords: " TextWrapping="Wrap" FontWeight="Bold" />             </StackPanel>         </Grid>


Then I attached the event handler within the Behavior.cs code:

this.AssociatedObject.MouseMove +=new MouseEventHandler(AssociatedObject_MouseMove);

Defined the event hanlder to display coordinates in textbloxk control:

 private void AssociatedObject_MouseMove(object sender, System.Windows.Input.MouseEventArgs args)         {             if (this.AssociatedObject != null)             {                 System.Windows.Point screenPoint = args.GetPosition(MapApplication.Current.Map);                 ESRI.ArcGIS.Client.Geometry.MapPoint mapPoint = MapApplication.Current.Map.ScreenToMap(screenPoint);                 TextBlock tb = MapApplication.Current.FindObjectInLayout("MapCoordsTextBlock") as TextBlock;                 tb.Text = string.Format("Map Coords: X = {0}, Y = {1}",                     Math.Round(mapPoint.X, 4), Math.Round(mapPoint.Y, 4));             }         }


Hope this helps for you and others.

Scott

View solution in original post

0 Kudos
6 Replies
CMICNRE
New Contributor II
Ok, so I added an event handler to the usercontrol xaml,

<Grid x:Name="LayoutRoot" Background="White" MouseMove="MyMap_MouseMove">

and now the coordinates are showing up when I move the mouse over the usercontrol panel.  How do I get coordinates from anywhere in the map?  I tried args.getPosition(null);, but that didn't work either.
0 Kudos
ScottFriedrich
New Contributor III
Laura,

I was able to display the mouse coordinates using a Behavior.  I implemented a behavior because I always want the coordinates to display and do not want to turn them off. 

First I added to the xaml of the Layout I am using the following:


<Grid Width="355" Height="65" HorizontalAlignment="Right" VerticalAlignment="Top" Margin="0,50,15,0" >             <Rectangle Stroke="Gray"  RadiusX="10" RadiusY="10" Fill="#77919191" Margin="0,0,0,6" >                 <Rectangle.Effect>                     <DropShadowEffect/>                 </Rectangle.Effect>             </Rectangle>             <Rectangle Fill="#FFFFFFFF" Stroke="DarkGray" RadiusX="5" RadiusY="5" Margin="10,10,10,15"  />             <StackPanel Canvas.Left="20" Canvas.Top="14" Margin="20,14,10,0">                                 <TextBlock x:Name="MapCoordsTextBlock"                      HorizontalAlignment="Left" VerticalAlignment="Center" Text="Map Coords: " TextWrapping="Wrap" FontWeight="Bold" />             </StackPanel>         </Grid>


Then I attached the event handler within the Behavior.cs code:

this.AssociatedObject.MouseMove +=new MouseEventHandler(AssociatedObject_MouseMove);

Defined the event hanlder to display coordinates in textbloxk control:

 private void AssociatedObject_MouseMove(object sender, System.Windows.Input.MouseEventArgs args)         {             if (this.AssociatedObject != null)             {                 System.Windows.Point screenPoint = args.GetPosition(MapApplication.Current.Map);                 ESRI.ArcGIS.Client.Geometry.MapPoint mapPoint = MapApplication.Current.Map.ScreenToMap(screenPoint);                 TextBlock tb = MapApplication.Current.FindObjectInLayout("MapCoordsTextBlock") as TextBlock;                 tb.Text = string.Format("Map Coords: X = {0}, Y = {1}",                     Math.Round(mapPoint.X, 4), Math.Round(mapPoint.Y, 4));             }         }


Hope this helps for you and others.

Scott
0 Kudos
AnthonyKeogh1
New Contributor III
Hi Scott,

I am doing something similar to what you have described and I have used your code as a starting point so thanks for that.
I was wondering how you are displaying the Map Coords text block in the map web part?
The only way I know of is to display it in a dialog box but as you can see in the screenshot attached this isn't ideal.

Thanks for any help,
Anthony
0 Kudos
AnthonyKeogh1
New Contributor III
Nevermind, I figured it out, you just add it as a child to the correct container.
0 Kudos
CMICNRE
New Contributor II
Scott,
Thanks for your help with the behavior, I was able to get that working with your code.
0 Kudos
CMICNRE
New Contributor II
Here is how I worked out my Show Map Coordinates behavior.  The coordinates are displayed in a TextBlock object in the layout.  If the spatial reference is Web Mercator, then the coordinates are converted to Lat/Long.  If the user holds down the left mouse button and drags the map, I attempted update the coordinates with an map ExtentChanging event handler (saw this in another post in Silverlight API forum.

Here is the coordinates textblock xaml:

<!--Show mouse coordinates in a textblock-->
<Grid Width="566" Height="35" VerticalAlignment="Bottom" Margin="5,10,5,5" d:LayoutOverrides="GridBox">
            <TextBlock x:Name="Coordinates" Visibility="Visible" HorizontalAlignment="Left" VerticalAlignment="Center" Text="Map Coordinates: " TextWrapping="Wrap" FontWeight="Normal" FontSize="9.333" />
</Grid>


Here is the behavior class MapCoordsBehavior.cs:

using System.ComponentModel.Composition;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Interactivity;
using ESRI.ArcGIS.Client;
using ESRI.ArcGIS.Client.Extensibility;
using ESRI.ArcGIS.Client.Geometry;
using ESRI.ArcGIS.Client.Projection;

namespace MyBehaviors.AddIns
{
    [Export(typeof(Behavior<Map>))]
    [DisplayName("Map coordinates in container")]
    [Category("My Behaviors")]
    [Description("Shows the mouse map coordinates in a framework element")]
    public class MapCoordsBehavior : Behavior<Map>
    {
        private string textBlockName = "Coordinates";
        private TextBlock coordTextBlock;
        private int wkid = -1;
        private string datumName = string.Empty;
        private System.Windows.Point screenPoint;
        private ESRI.ArcGIS.Client.Geometry.MapPoint mapPoint;
        private ESRI.ArcGIS.Client.Projection.WebMercator webMercator;
        private ESRI.ArcGIS.Client.Geometry.Geometry geometry;

        #region Behavior Overrides
        protected override void OnAttached()
        {
            base.OnAttached();

            // Add a handler to the map MouseMove event
            this.AssociatedObject.MouseMove += map_MouseMove;
            this.AssociatedObject.ExtentChanging += map_ExtentChanging;

            //Find the coordinate textBlock framework object
            this.coordTextBlock =  MapApplication.Current.FindObjectInLayout(textBlockName) as TextBlock;

            //Get the map's spatial reference and assign the datum name, if known
            this.wkid = MapApplication.Current.Map.Extent.SpatialReference.WKID;
            this.webMercator = new ESRI.ArcGIS.Client.Projection.WebMercator();
            if (this.wkid == 102100) { this.datumName = "(WGS84)"; }
           
        }

        protected override void OnDetaching()
        {
            base.OnDetaching();

            // Remove the handler from the map MouseMove event
            this.AssociatedObject.MouseMove -= map_MouseMove;
            this.AssociatedObject.ExtentChanging -= map_ExtentChanging;
        }
        #endregion

        #region Event Handlers
        private void map_MouseMove(object sender, System.Windows.Input.MouseEventArgs e)
        {
            this.screenPoint = e.GetPosition(MapApplication.Current.Map);
            UpdateMouseCoordinates();
        }

        void map_ExtentChanging(object sender, ExtentEventArgs e)
        {
            //Updates the map coordinates when the map extent changes while user is holding down left mouse button
            UpdateMouseCoordinates();
        }

        private void UpdateMouseCoordinates()
        {
            if (this.AssociatedObject != null)
            {
                //If the textblock wasn't found then return
                if (this.coordTextBlock == null) { return; }

                //Otherwise, convert the screen point to map coordinates
                this.mapPoint = MapApplication.Current.Map.ScreenToMap(this.screenPoint);

                //Convert from Web Mercator (WKID=102100) to geographic WGS84 coordinates (WKID=4326)
                if (this.wkid == 102100)
                {
                    geometry = webMercator.ToGeographic(mapPoint);
                    if (geometry != null) { mapPoint = (MapPoint)geometry; }
                }

                this.coordTextBlock.Text = string.Format("Lat {0:f4}, Long {1:f4} {2}", System.Math.Round(mapPoint.Y, 4), System.Math.Round(mapPoint.X, 4), this.datumName);
            }
        }
        #endregion
    }
}

0 Kudos