I'm trying to draw a line on layout view on ArcMap with C# and ArcObjects. I'm working on this sample. But I have some problems.
1.) This code for draw line on data view but I need to draw line on layout view(In box frame).I want to see properties of line element when I selected my line Item.
2.) When I click on this line in ArcMap, It become invisible..why is this happening?
This is Code Sample :
protected override void OnClick()
{
//drawing a polyline
Point p1 = new PointClass();
p1.X = 10; p1.Y = 10;
IPoint p2 = new PointClass();
p2.X = 20; p2.Y = 20;
IPoint p3 = new PointClass();
p3.X = 35; p3.Y = 15;
IPoint p4 = new PointClass();
p4.X = 40; p4.Y = 17;
IPoint p5 = new PointClass();
p5.X = 50; p5.Y = 19;
IPoint p6 = new PointClass();
p6.X = 60; p6.Y = 18;
IPolyline polyline = new PolylineClass();
IPointCollection pointColl = polyline as IPointCollection;
pointColl.AddPoint(p1);
pointColl.AddPoint(p2);
pointColl.AddPoint(p3);
pointColl.AddPoint(p4);
pointColl.AddPoint(p5);
pointColl.AddPoint(p6);
IMxDocument mxdoc = ArcMap.Application.Document as IMxDocument;
IActiveView activeView = mxdoc.ActiveView;
IScreenDisplay screenDisp = activeView.ScreenDisplay;
short screenCache = Convert.ToInt16(esriScreenCache.esriNoScreenCache);
screenDisp.StartDrawing(screenDisp.hDC, screenCache);
IRgbColor color = new RgbColorClass();
color.Red = 0; color.Blue = 0; color.Green = 0;
ISimpleLineSymbol simpleLineSymbol = new SimpleLineSymbolClass();
simpleLineSymbol.Color = color;
simpleLineSymbol.Width = 1;
screenDisp.SetSymbol(simpleLineSymbol as ISymbol);
screenDisp.DrawPolyline(polyline);
screenDisp.FinishDrawing();
}
2 Answers 2
The reason why this code is failing is that you are writing to the screen cache, which you are obtaining from the activeview
and this could be the map
or pagelayout
; you need to be more explicit.
As soon as there is any sort of screen refresh you loose the graphic you have drawn. If you want graphics to persist you need to be storing them in the PageLayout graphics container. The following VBA code shows you how to do this using your example points.
Public Sub drawline()
' Create a polyline
Dim p1 As IPoint
Set p1 = New Point
p1.X = 10
p1.Y = 10
Dim p2 As IPoint
Set p2 = New Point
p2.X = 20
p2.Y = 20
Dim p3 As IPoint
Set p3 = New Point
p3.X = 30
p3.Y = 15
Dim p4 As IPoint
Set p4 = New Point
p4.X = 40
p4.Y = 15
Dim p5 As IPoint
Set p5 = New Point
p5.X = 50
p5.Y = 19
Dim p6 As IPoint
Set p6 = New Point
p6.X = 60
p6.Y = 18
Dim pPolyline As IPolyline
Set pPolyline = New Polyline
Dim pPointColl As IPointCollection
Set pPointColl = pPolyline
pPointColl.AddPoint p1
pPointColl.AddPoint p2
pPointColl.AddPoint p3
pPointColl.AddPoint p4
pPointColl.AddPoint p5
pPointColl.AddPoint p6
' Create a colour
Dim pColour As IRgbColor
Set pColour = New RgbColor
With pColour
.Red = 0
.Blue = 0
.Green = 0
End With
' Create a line symbol
Dim pSimpleLineSymbol As ISimpleLineSymbol
Set pSimpleLineSymbol = New SimpleLineSymbol
With pSimpleLineSymbol
.Width = 1
.Style = esriSLSSolid
.Color = pColour
End With
' Create a line element, this is the graphic that will get added to the container
Dim pElement As IElement
Set pElement = New LineElement
pElement.Geometry = pPolyline
Dim pLineElement As ILineElement
Set pLineElement = pElement
pLineElement.Symbol = pSimpleLineSymbol
' Get the MXD
Dim pMXD As IMxDocument
Set pMXD = ThisDocument
' Get a handle on the page layout
Dim pPageLayout As IPageLayout
Set pPageLayout = pMXD.PageLayout
' Get the graphics container of the PAGELAYOUT
Dim pGraphicsContainer As IGraphicsContainer
Set pGraphicsContainer = pPageLayout
' Add element and refresh
pGraphicsContainer.AddElement pElement, 0
Dim pActiveView As IActiveView
Set pActiveView = pPageLayout
pActiveView.Refresh
End Sub
Note: the coordinates are interpreted as page coordinates, not geographic so the line that gets created is much larger than your page.
this is c# code for your solution :
protected override void OnClick() {
//Create a polyline
Point p1 = new PointClass();
p1.X = 10; p1.Y = 10;
IPoint p2 = new PointClass();
p2.X = 20; p2.Y = 20;
IPoint p3 = new PointClass();
p3.X = 35; p3.Y = 15;
IPoint p4 = new PointClass();
p4.X = 40; p4.Y = 17;
IPoint p5 = new PointClass();
p5.X = 50; p5.Y = 19;
IPoint p6 = new PointClass();
p6.X = 60; p6.Y = 18;
IPolyline polyline = new PolylineClass();
IPointCollection pointColl = polyline as IPointCollection;
pointColl.AddPoint(p1);
pointColl.AddPoint(p2);
pointColl.AddPoint(p3);
pointColl.AddPoint(p4);
pointColl.AddPoint(p5);
pointColl.AddPoint(p6);
// Create a colour
IRgbColor color = new RgbColorClass();
color.Red = 0; color.Blue = 0; color.Green = 0;
// Create a line symbol
ISimpleLineSymbol simpleLineSymbol = new SimpleLineSymbolClass();
simpleLineSymbol.Color = color;
simpleLineSymbol.Width = 1;
// Create a line element, this is the graphic that will get added to container
IElement element = new LineElement();
element.Geometry = polyline;
ILineElement lineElement;
lineElement = element as ILineElement;
lineElement.Symbol = simpleLineSymbol;
// Get the Mxd
IMxDocument mxdoc = ArcMap.Application.Document as IMxDocument;
// Get the handle on the page layout
IPageLayout pageLayout = new PageLayout();
pageLayout = mxdoc.PageLayout;
// Get the graphics container of the PageLayout
IGraphicsContainer graphicsContainer = pageLayout as IGraphicsContainer;
// Add element an refresh
graphicsContainer.AddElement(element, 0);
IActiveView activeView = pageLayout as IActiveView;
activeView.Refresh();
}