I have a polygon drawn on top of a layer using the graphicsContainer of the current activeView, then I want to be able to show a custom context menu if the user right clicks INSIDE the polygon. So I have to figure out a way to determine if the mouse click falls within the polygon. I have tried to use the IRelationalOperator2 as suggested in this question Does anyone know a function to determine if a Point exists within a polygon?, but I can't seem to get it working properly. Here is what I have so far:
System.Drawing.Point screenMousePoint = System.Windows.Forms.Form.MousePosition;
IPoint screenPoint = new Point();
screenPoint.X = screenMousePoint.X;
screenPoint.Y = screenMousePoint.Y;
IPoint mapPoint = this.controller.GetMapCoordinatesFromScreenCoordinates(screenPoint, activeView);
// this.currentDefinedArea is a polygon
IRelationalOperator2 relation = this.currentDefinedArea as IRelationalOperator2;
if (relation.Contains(mapPoint))
{
// Show context menu
}
The "GetMapCoordinatesFromScreenCoordinates" method looks like this, and it's one of the snippets that is included in arcobjects:
public IPoint GetMapCoordinatesFromScreenCoordinates(IPoint screenPoint, IActiveView activeView)
{
if (screenPoint == null || screenPoint.IsEmpty || activeView == null)
{
return null;
}
IScreenDisplay screenDisplay = activeView.ScreenDisplay;
IDisplayTransformation displayTransformation = screenDisplay.DisplayTransformation;
return displayTransformation.ToMapPoint((System.Int32)screenPoint.X, (System.Int32)screenPoint.Y);
}
I found out what was causing the above code to fail. Using:
System.Drawing.Point screenMousePoint = System.Windows.Forms.Form.MousePosition;
…gives a different set of X, Y coordinates than using the MouseEventArgs provided by the OnMouseDown method. Don't know why I wasn't using them in the first place…here's how my working code looks:
protected override void OnMouseDown(ESRI.ArcGIS.Desktop.AddIns.Tool.MouseEventArgs arg)
{
if (arg.Button == System.Windows.Forms.MouseButtons.Right)
{
if (this.controller.CurrentDefinedArea != null)
{
IPoint screenPoint = new Point();
screenPoint.X = arg.X;
screenPoint.Y = arg.Y;
IPoint mapPoint = this.controller.GetMapCoordinatesFromScreenCoordinates(screenPoint, activeView);
IRelationalOperator2 relation = this.controller.CurrentDefinedArea as IRelationalOperator2;
if (relation.Contains(mapPoint))
{
this.controller.CreateContextMenu(ArcMap.Application);
}
}
}
}
Best Answer
As Peter Krebs has suggested on mouse down use IDisplayTransformation.ToMapPoint to assign the XY info to a point graphic. You can then use that graphic as a selector against your polygon layer.