I have cobbled together some code to set halos around text labels for a given feature layer in ArcMap. The code work in the sense it sets the relevant properties. The problem I'm having is having the newly formatted labels updated in the display afterwards. The usual IDocument.ActiveView.Refresh doesn't work. I'm sure there is an easy fix. Any suggestions?
Cheers
public void add_halo(IGeoFeatureLayer fl) | |
{ |
IAnnotateLayerPropertiesCollection pAnno = fl.AnnotationProperties; | |
pAnno.Clear(); |
IAnnotateLayerProperties labelEngineProperties = new LabelEngineLayerProperties() as IAnnotateLayerProperties; | |
ILabelEngineLayerProperties pLprop = labelEngineProperties as ILabelEngineLayerProperties; |
ITextSymbol pTextSymbol = pLprop.Symbol; | |
IFillSymbol pMaskFillSymbol; | |
IRgbColor pMaskFillColor; |
IMask pMask = (IMask)pTextSymbol; | |
pMask.MaskStyle = esriMaskStyle.esriMSHalo; | |
pMask.MaskSize = 2; // ' halo size; | |
pMaskFillSymbol = new SimpleFillSymbol(); | |
pMaskFillColor = new RgbColor(); | |
pMaskFillColor.Red = 255; | |
pMaskFillColor.Green = 255; | |
pMaskFillColor.Blue = 255; | |
pMaskFillSymbol.Color = pMaskFillColor; | |
pMaskFillSymbol.Outline = null; | |
pMask.MaskSymbol = pMaskFillSymbol; |
pTextSymbol.Size = 10; | |
pAnno.Add((IAnnotateLayerProperties)pLprop); |
fl.DisplayAnnotation = true; | |
} |
ArcGIS Desktop 10.3
Win 7
VS 2013 Express
Solved! Go to Solution.
Sorry I didn't notice before you were creating a new LabelEngineLayerProperties object.
You can get the current object by querying the AnnotateLayerPropertiesCollection.
There should be no need to clear and re-add it:
Dim alpColl As IAnnotateLayerPropertiesCollection
Set alpColl = gfl.AnnotationProperties
Dim alp As IAnnotateLayerProperties
alpColl.QueryItem 0, alp, Nothing, Nothing 'query first anno class
Dim leProp As IAnnotateLayerProperties
Set leProp = alp 'New LabelEngineLayerProperties
Dim lProp As ILabelEngineLayerProperties
Set lProp = leProp
I'm not really sure what might be happening, but one thing you might do is to try to force a redraw by doing something like setting the focus map's mapscale property equal to the current mapscale. I think that'll cause a redraw/refresh.
Thanks for the suggestion River. Unfortunately that didn't work. So far the code above does make the necessary changes in the label properties but any type of refresh code doesn't make the changes in the display view. The only way to do it is open up the properties, toggle something to get the 'Apply' button activated, then press Apply. I ran code and only toggled the IGeoFeatureLayer.DisplayAnnotation and it worked fine with the usual ActiveView.Refresh method. This leads me to think that something is not being set or updated correctly in the ILabelEngineLayerProperties properties before being added to the IAnnotateLayerPropertiesCollection at the end. Any other suggestions out there?
Sorry I don't have time to test this; usually you'll need to set the updates back to the original object at the end.
Something like:
fl.AnnotationProperties = pAnno;
Thanks for the suggestion Jeff. Unfortunately that didn't work. The properties seem to be getting set fine. It's just that the display isn't being updated to reflect the new settings and the usual display refresh methods don't work. I was concerned that the pAnno.Clear() statement may have been removing something that I wasn't resetting and therefore hindering the display refresh process. No idea what property that could be though if that is the case.
Sorry I didn't notice before you were creating a new LabelEngineLayerProperties object.
You can get the current object by querying the AnnotateLayerPropertiesCollection.
There should be no need to clear and re-add it:
Dim alpColl As IAnnotateLayerPropertiesCollection
Set alpColl = gfl.AnnotationProperties
Dim alp As IAnnotateLayerProperties
alpColl.QueryItem 0, alp, Nothing, Nothing 'query first anno class
Dim leProp As IAnnotateLayerProperties
Set leProp = alp 'New LabelEngineLayerProperties
Dim lProp As ILabelEngineLayerProperties
Set lProp = leProp
That did it Jeff! Thanks for the example code as well.
This is the code that now work well.
public void add_halo(IGeoFeatureLayer fl) | |
{ |
fl.DisplayAnnotation = false; | |
pDoc.ActiveView.Refresh(); |
IElementCollection ec1; | |
IElementCollection ec2; |
IAnnotateLayerPropertiesCollection pAnno = fl.AnnotationProperties; | ||
IAnnotateLayerProperties alp; | ||
pAnno.QueryItem(0, out alp, out ec1, out ec2); // | 'query first anno class |
IAnnotateLayerProperties labelEngineProperties = alp; // new LabelEngineLayerProperties() as IAnnotateLayerProperties; | |
ILabelEngineLayerProperties pLprop = labelEngineProperties as ILabelEngineLayerProperties; |
ITextSymbol pTextSymbol = pLprop.Symbol; | |
IFillSymbol pMaskFillSymbol; | |
IRgbColor pMaskFillColor; |
IMask pMask = (IMask)pTextSymbol; | |
pMask.MaskStyle = esriMaskStyle.esriMSHalo; | |
pMask.MaskSize = 2; // ' halo size; | |
pMaskFillSymbol = new SimpleFillSymbol(); | |
pMaskFillColor = new RgbColor(); | |
pMaskFillColor.Red = 255; | |
pMaskFillColor.Green = 255; | |
pMaskFillColor.Blue = 255; | |
pMaskFillSymbol.Color = pMaskFillColor; | |
pMaskFillSymbol.Outline = null; | |
pMask.MaskSymbol = pMaskFillSymbol; |
pTextSymbol.Size = 10; | |
fl.AnnotationProperties = pAnno; |
fl.DisplayAnnotation = true; | |
fl = null; |
} |