About the Use an AlgorithmicColorRamp to color a ClassBreaksRenderer Sample
[C#]
AlgorithmicColorRamp.cs
using ESRI.ArcGIS.ADF.BaseClasses;
using ESRI.ArcGIS.ADF.CATIDs;
using ESRI.ArcGIS.ArcMapUI;
using ESRI.ArcGIS.Carto;
using ESRI.ArcGIS.Display;
using ESRI.ArcGIS.esriSystem;
using ESRI.ArcGIS.Framework;
using ESRI.ArcGIS.Geometry;
using ESRI.ArcGIS.SystemUI;
using Microsoft.VisualBasic.Compatibility.VB6;
using System;
using System.Collections;
using System.Data;
using System.Diagnostics;
using System.Drawing;
using System.Runtime.InteropServices;
using System.Windows.Forms;
namespace AlgorithmicColorRamp
{
[System.Runtime.InteropServices.ProgId("AlgorithmicColorRamp.clsAlgColorRamp")]
public class AlgorithmicColorRamp : ESRI.ArcGIS.Desktop.AddIns.Button
{
private frmAlgorithmicColorRamp frmAlgoColorRamp = new frmAlgorithmicColorRamp();
public AlgorithmicColorRamp()
{
}
protected override void OnClick()
{
//
// When the utility is selected, check that we have a currently selected
// feature layer with a ClassBreaksRenderer already set. First we get the contents view.
//
IContentsView ContentsView = null;
ContentsView = ArcMap.Document.CurrentContentsView;
//
// If we have a DisplayView active
//
object VarSelectedItem = null;
IGeoFeatureLayer GeoFeatureLayer = null;
IClassBreaksRenderer ClassBreaksRenderer = null;
IEnumColors pColors = null;
int lngCount = 0;
IHsvColor HsvColor = null;
IClone ClonedSymbol = null;
ISymbol NewSymbol = null;
IActiveView ActiveView = null; //AlgorithimcColorRamp contains HSV colors.
if (ContentsView is TOCDisplayView)
{
if (ContentsView.SelectedItem is DBNull)
{
//
// If we don't have anything selected.
//
MessageBox.Show("SelectedItem is Null C#." + "Select a layer in the Table of Contents.", "No Layer Selected", MessageBoxButtons.OK, MessageBoxIcon.Information);
return;
}
//
// Get the selected Item.
//
VarSelectedItem = ContentsView.SelectedItem;
//
// Selected Item should implement the IGeoFeatureLayer interface - therefore we
// have selected a feature layer with a Renderer property (Note: Other interfaces
// also have a Renderer property, which may behave differently.
//
if (VarSelectedItem is IGeoFeatureLayer)
{
GeoFeatureLayer = (IGeoFeatureLayer)VarSelectedItem;
//
// Set the cached property to true, so we can refresh this layer
// without refreshing all the layers, when we have changed the symbols.
//
GeoFeatureLayer.Cached = true;
//
// Check we have an existing ClassBreaksRenderer.
//
if (GeoFeatureLayer.Renderer is IClassBreaksRenderer)
{
ClassBreaksRenderer = (IClassBreaksRenderer)GeoFeatureLayer.Renderer;
//
// If successful so far we can go ahead and open the Form. This allows the
// user to change the properties of the new RandomColorRamp.
//
frmAlgoColorRamp.m_lngClasses = ClassBreaksRenderer.BreakCount;
frmAlgoColorRamp.ShowDialog();
//
// Return the selected colors enumeration.
pColors = frmAlgoColorRamp.m_enumNewColors;
if (pColors == null)
{
//
// User has cancelled the form, or not set a ramp.
//
//MsgBox("Colors object is empty. Exit Sub")
return;
}
//
// Set the new random colors onto the Symbol array of the ClassBreaksRenderer.
//
pColors.Reset(); // Because you never know if the enumeration has been
// iterated before being passed back.
int tempFor1 = ClassBreaksRenderer.BreakCount;
for (lngCount = 0; lngCount < tempFor1; lngCount++)
{
//
// For each Value in the ClassBreaksRenderer, we clone the existing
// Fill symbol (so that all the properties are faithful preserved,
// and set its color from our new AlgorithmicColorRamp.
//
IClone symClone;
symClone = (IClone)ClassBreaksRenderer.get_Symbol(lngCount);
ClonedSymbol = CloneMe(ref (symClone));
//
// Now the ClonedSymbol variable holds a copy of the existing
// Symbol, we can change the assigned Color. We set the new
// symbol onto the Symbol array of the Renderer. '
//
HsvColor = (IHsvColor)pColors.Next();
NewSymbol = SetColorOfUnknownSymbol(ClonedSymbol, HsvColor);
if (NewSymbol != null)
ClassBreaksRenderer.set_Symbol(lngCount, NewSymbol);
}
//
// Refresh the table of contents and the changed layer.
//
ActiveView = (IActiveView)ArcMap.Document.FocusMap;
ActiveView.ContentsChanged();
ArcMap.Document.UpdateContents();
ActiveView.PartialRefresh(esriViewDrawPhase.esriViewGeography, GeoFeatureLayer, null);
}
}
}
}
public IClone CloneMe(ref IClone OriginalClone)
{
IClone tempCloneMe = null;
//
// This function clones the input object.
//
tempCloneMe = null;
if (OriginalClone != null)
tempCloneMe = OriginalClone.Clone();
return tempCloneMe;
}
private ISymbol SetColorOfUnknownSymbol(IClone ClonedSymbol, IColor Color)
{
ISymbol tempSetColorOfUnknownSymbol = null;
//
// This function takes an IClone interface, works out the underlying coclass
// (which should be some kind of symbol) and then sets the Color property
// according to the passed in color.
//
tempSetColorOfUnknownSymbol = null;
if (ClonedSymbol == null)
return tempSetColorOfUnknownSymbol;
//
// Here we figure out which kind of symbol we have. For the simple symbol
// types, simply setting the color property is OK. However, more complex
// symbol types require further investigation.
//
IFillSymbol FillSymbol = null;
IMarkerFillSymbol MarkerFillSymbol = null;
IMarkerSymbol MarkerSymbol_A = null;
ILineFillSymbol LineFillSymbol = null;
ILineSymbol LineSymbol = null;
IPictureFillSymbol PictureFillSymbol = null;
IMarkerSymbol MarkerSymbol_B = null;
IPictureMarkerSymbol PictureMarkerSymbol = null;
IMarkerLineSymbol MarkerLineSymbol = null;
IMarkerSymbol MarkerSymbol_C = null;
ILineSymbol LineSymbol_B = null;
if (ClonedSymbol is ISymbol)
{
//
// Check for Fill symbols.
//
if (ClonedSymbol is IFillSymbol)
{
//
// Check for SimpleFillSymbols or MultiLevelFillSymbols.
//
if ((ClonedSymbol is ISimpleFillSymbol) | (ClonedSymbol is IMultiLayerFillSymbol))
{
FillSymbol = (IFillSymbol)ClonedSymbol;
//
// Here we simply change the color of the Fill.
//
FillSymbol.Color = Color;
tempSetColorOfUnknownSymbol = (ISymbol)FillSymbol;
//
// Check for MarkerFillSymbols.
//
}
else if (ClonedSymbol is IMarkerFillSymbol)
{
MarkerFillSymbol = (IMarkerFillSymbol)ClonedSymbol;
//
// Here we change the color of the MarkerSymbol.
//
MarkerSymbol_A = (IMarkerSymbol)SetColorOfUnknownSymbol((IClone)MarkerFillSymbol.MarkerSymbol, Color);
MarkerFillSymbol.MarkerSymbol = MarkerSymbol_A;
tempSetColorOfUnknownSymbol = (ISymbol)MarkerFillSymbol;
//
// Check for LineFillSymbols.
//
}
else if (ClonedSymbol is ILineFillSymbol)
{
LineFillSymbol = (ILineFillSymbol)ClonedSymbol;
//
// Here we change the color of the LineSymbol.
//
LineSymbol = (ILineSymbol)SetColorOfUnknownSymbol((IClone)LineFillSymbol.LineSymbol, Color);
LineFillSymbol.LineSymbol = LineSymbol;
tempSetColorOfUnknownSymbol = (ISymbol)LineFillSymbol;
//
// Check for PictureFillSymbols.
//
}
else if (ClonedSymbol is IPictureFillSymbol)
{
PictureFillSymbol = (IPictureFillSymbol)ClonedSymbol;
//
// Here we simply change the color of the BackgroundColor.
//
PictureFillSymbol.BackgroundColor = Color;
tempSetColorOfUnknownSymbol = (ISymbol)PictureFillSymbol;
}
//
// Check for Marker symbols.
//
}
else if (ClonedSymbol is IMarkerSymbol)
{
//
// Check for SimpleMarkerSymbols, ArrowMarkerSymbols or
// CharacterMarkerSymbols.
//
if ((ClonedSymbol is IMultiLayerMarkerSymbol) | (ClonedSymbol is ISimpleMarkerSymbol) | (ClonedSymbol is IArrowMarkerSymbol) | (ClonedSymbol is ICharacterMarkerSymbol))
{
MarkerSymbol_B = (IMarkerSymbol)ClonedSymbol;
//
// For these types, we simply change the color property.
//
MarkerSymbol_B.Color = Color;
tempSetColorOfUnknownSymbol = (ISymbol)MarkerSymbol_B;
//
// Check for PictureMarkerSymbols.
//
}
else if (ClonedSymbol is IPictureMarkerSymbol)
{
PictureMarkerSymbol = (IPictureMarkerSymbol)ClonedSymbol;
//
// Here we change the BackgroundColor property.
//
PictureMarkerSymbol.Color = Color;
tempSetColorOfUnknownSymbol = (ISymbol)PictureMarkerSymbol;
}
//
// Check for Line symbols.
//
}
else if (ClonedSymbol is ILineSymbol)
{
//
// Check for MarkerLine symbols.
//
if (ClonedSymbol is IMarkerLineSymbol)
{
MarkerLineSymbol = (IMarkerLineSymbol)ClonedSymbol;
//
// Here we change the color of the MarkerSymbol.
//
MarkerSymbol_C = (IMarkerSymbol)SetColorOfUnknownSymbol((IClone)MarkerLineSymbol.MarkerSymbol, Color);
MarkerLineSymbol.MarkerSymbol = MarkerSymbol_C;
tempSetColorOfUnknownSymbol = (ISymbol)MarkerLineSymbol;
//
// Check for other Line symbols.
//
}
else if ((ClonedSymbol is ISimpleLineSymbol) | (ClonedSymbol is IHashLineSymbol) | (ClonedSymbol is ICartographicLineSymbol))
{
LineSymbol_B = (ILineSymbol)ClonedSymbol;
LineSymbol_B.Color = Color;
tempSetColorOfUnknownSymbol = (ISymbol)LineSymbol_B;
}
}
}
return tempSetColorOfUnknownSymbol;
}
protected override void OnUpdate()
{
Enabled = ArcMap.Application != null;
}
}
}
[Visual Basic .NET]
AlgorithmicColorRamp.vb
Option Strict Off
Option Explicit On
Imports ESRI.ArcGIS.ArcMapUI
Imports ESRI.ArcGIS.Carto
Imports ESRI.ArcGIS.Display
Imports ESRI.ArcGIS.esriSystem
Imports ESRI.ArcGIS.Framework
Imports ESRI.ArcGIS.Geometry
Imports ESRI.ArcGIS.SystemUI
Imports ESRI.ArcGIS.ADF.BaseClasses
Imports ESRI.ArcGIS.ADF.CATIDs
Imports System
Imports System.Collections
Imports System.Data
Imports System.Diagnostics
Imports System.Drawing
Imports System.Runtime.InteropServices
Imports System.Windows.Forms
Public Class AlgorithmicColorRamp
Inherits ESRI.ArcGIS.Desktop.AddIns.Button
Private frmAlgoColorRamp As New frmAlgorithmicColorRamp()
Public Sub New()
End Sub
Protected Overrides Sub OnClick()
'
' When the utility is selected, check that we have a currently selected
' feature layer with a ClassBreaksRenderer already set. First we get the contents view.
'
Dim ContentsView As IContentsView
ContentsView = My.ArcMap.Document.CurrentContentsView
'
' If we have a DisplayView active
'
Dim VarSelectedItem As Object
Dim GeoFeatureLayer As IGeoFeatureLayer
Dim ClassBreaksRenderer As IClassBreaksRenderer
Dim pColors As IEnumColors
Dim lngCount As Integer
Dim HsvColor As IHsvColor
Dim ClonedSymbol As IClone
Dim NewSymbol As ISymbol
Dim ActiveView As IActiveView 'AlgorithimcColorRamp contains HSV colors.
If TypeOf ContentsView Is TOCDisplayView Then
If IsDBNull(ContentsView.SelectedItem) Then
'
' If we don't have anything selected.
'
'Err.Raise(94, , "SelectedItem is Null" & vbNewLine & "Select a layer in the Table of Contents to rename")
MsgBox("SelectedItem is Null." & "Select a layer in the Table of Contents to rename.", MsgBoxStyle.Information, "No Layer Selected")
Exit Sub
End If
'
' Get the selected Item.
'
VarSelectedItem = ContentsView.SelectedItem
'
' Selected Item should implement the IGeoFeatureLayer interface - therefore we
' have selected a feature layer with a Renderer property (Note: Other interfaces
' also have a Renderer property, which may behave differently.
'
If TypeOf VarSelectedItem Is IGeoFeatureLayer Then
GeoFeatureLayer = VarSelectedItem
'
' Set the cached property to true, so we can refresh this layer
' without refreshing all the layers, when we have changed the symbols.
'
GeoFeatureLayer.Cached = True
'
' Check we have an existing ClassBreaksRenderer.
'
If TypeOf GeoFeatureLayer.Renderer Is IClassBreaksRenderer Then
ClassBreaksRenderer = GeoFeatureLayer.Renderer
'
' If successful so far we can go ahead and open the Form. This allows the
' user to change the properties of the new RandomColorRamp.
'
frmAlgoColorRamp.m_lngClasses = ClassBreaksRenderer.BreakCount
frmAlgoColorRamp.ShowDialog()
'
' Return the selected colors enumeration.
pColors = frmAlgoColorRamp.m_enumNewColors
If pColors Is Nothing Then
'
' User has cancelled the form, or not set a ramp.
'
'MsgBox("Colors object is empty. Exit Sub")
Exit Sub
End If
'
' Set the new random colors onto the Symbol array of the ClassBreaksRenderer.
'
pColors.Reset() ' Because you never know if the enumeration has been
' iterated before being passed back.
For lngCount = 0 To ClassBreaksRenderer.BreakCount - 1
'
' For each Value in the ClassBreaksRenderer, we clone the existing
' Fill symbol (so that all the properties are faithful preserved,
' and set its color from our new AlgorithmicColorRamp.
'
ClonedSymbol = CloneMe(ClassBreaksRenderer.Symbol(lngCount))
'
' Now the ClonedSymbol variable holds a copy of the existing
' Symbol, we can change the assigned Color. We set the new
' symbol onto the Symbol array of the Renderer. '
'
HsvColor = pColors.Next
NewSymbol = SetColorOfUnknownSymbol(ClonedSymbol, HsvColor)
If Not NewSymbol Is Nothing Then
ClassBreaksRenderer.Symbol(lngCount) = NewSymbol
End If
Next lngCount
'
' Refresh the table of contents and the changed layer.
'
ActiveView = My.ArcMap.Document.FocusMap
ActiveView.ContentsChanged()
My.ArcMap.Document.UpdateContents()
ActiveView.PartialRefresh(esriViewDrawPhase.esriViewGeography, GeoFeatureLayer, Nothing)
End If
End If
End If
End Sub
Public Function CloneMe(ByRef OriginalClone As IClone) As IClone
'
' This function clones the input object.
'
CloneMe = Nothing
If Not OriginalClone Is Nothing Then
CloneMe = OriginalClone.Clone
End If
End Function
Private Function SetColorOfUnknownSymbol(ByVal ClonedSymbol As IClone, ByVal Color As IColor) As ISymbol
'
' This function takes an IClone interface, works out the underlying coclass
' (which should be some kind of symbol) and then sets the Color property
' according to the passed in color.
'
SetColorOfUnknownSymbol = Nothing
If ClonedSymbol Is Nothing Then
Exit Function
End If
'
' Here we figure out which kind of symbol we have. For the simple symbol
' types, simply setting the color property is OK. However, more complex
' symbol types require further investigation.
'
Dim FillSymbol As IFillSymbol
Dim MarkerFillSymbol As IMarkerFillSymbol
Dim MarkerSymbol_A As IMarkerSymbol
Dim LineFillSymbol As ILineFillSymbol
Dim LineSymbol As ILineSymbol
Dim PictureFillSymbol As IPictureFillSymbol
Dim MarkerSymbol_B As IMarkerSymbol
Dim PictureMarkerSymbol As IPictureMarkerSymbol
Dim MarkerLineSymbol As IMarkerLineSymbol
Dim MarkerSymbol_C As IMarkerSymbol
Dim LineSymbol_B As ILineSymbol
If TypeOf ClonedSymbol Is ISymbol Then
'
' Check for Fill symbols.
'
If TypeOf ClonedSymbol Is IFillSymbol Then
'
' Check for SimpleFillSymbols or MultiLevelFillSymbols.
'
If (TypeOf ClonedSymbol Is ISimpleFillSymbol) Or (TypeOf ClonedSymbol Is IMultiLayerFillSymbol) Then
FillSymbol = ClonedSymbol
'
' Here we simply change the color of the Fill.
'
FillSymbol.Color = Color
SetColorOfUnknownSymbol = FillSymbol
'
' Check for MarkerFillSymbols.
'
ElseIf TypeOf ClonedSymbol Is IMarkerFillSymbol Then
MarkerFillSymbol = ClonedSymbol
'
' Here we change the color of the MarkerSymbol.
'
MarkerSymbol_A = SetColorOfUnknownSymbol(MarkerFillSymbol.MarkerSymbol_A, Color)
MarkerFillSymbol.MarkerSymbol = MarkerSymbol_A
SetColorOfUnknownSymbol = MarkerFillSymbol
'
' Check for LineFillSymbols.
'
ElseIf TypeOf ClonedSymbol Is ILineFillSymbol Then
LineFillSymbol = ClonedSymbol
'
' Here we change the color of the LineSymbol.
'
LineSymbol = SetColorOfUnknownSymbol(LineFillSymbol.LineSymbol, Color)
LineFillSymbol.LineSymbol = LineSymbol
SetColorOfUnknownSymbol = LineFillSymbol
'
' Check for PictureFillSymbols.
'
ElseIf TypeOf ClonedSymbol Is IPictureFillSymbol Then
PictureFillSymbol = ClonedSymbol
'
' Here we simply change the color of the BackgroundColor.
'
PictureFillSymbol.BackgroundColor = Color
SetColorOfUnknownSymbol = PictureFillSymbol
End If
'
' Check for Marker symbols.
'
ElseIf TypeOf ClonedSymbol Is IMarkerSymbol Then
'
' Check for SimpleMarkerSymbols, ArrowMarkerSymbols or
' CharacterMarkerSymbols.
'
If (TypeOf ClonedSymbol Is IMultiLayerMarkerSymbol) Or (TypeOf ClonedSymbol Is ISimpleMarkerSymbol) Or (TypeOf ClonedSymbol Is IArrowMarkerSymbol) Or (TypeOf ClonedSymbol Is ICharacterMarkerSymbol) Then
MarkerSymbol_B = ClonedSymbol
'
' For these types, we simply change the color property.
'
MarkerSymbol_B.Color = Color
SetColorOfUnknownSymbol = MarkerSymbol_B
'
' Check for PictureMarkerSymbols.
'
ElseIf TypeOf ClonedSymbol Is IPictureMarkerSymbol Then
PictureMarkerSymbol = ClonedSymbol
'
' Here we change the BackgroundColor property.
'
PictureMarkerSymbol.Color = Color
SetColorOfUnknownSymbol = PictureMarkerSymbol
End If
'
' Check for Line symbols.
'
ElseIf TypeOf ClonedSymbol Is ILineSymbol Then
'
' Check for MarkerLine symbols.
'
If TypeOf ClonedSymbol Is IMarkerLineSymbol Then
MarkerLineSymbol = ClonedSymbol
'
' Here we change the color of the MarkerSymbol.
'
MarkerSymbol_C = SetColorOfUnknownSymbol(MarkerLineSymbol.MarkerSymbol, Color)
MarkerLineSymbol.MarkerSymbol = MarkerSymbol_C
SetColorOfUnknownSymbol = MarkerLineSymbol
'
' Check for other Line symbols.
'
ElseIf (TypeOf ClonedSymbol Is ISimpleLineSymbol) Or (TypeOf ClonedSymbol Is IHashLineSymbol) Or (TypeOf ClonedSymbol Is ICartographicLineSymbol) Then
LineSymbol_B = ClonedSymbol
LineSymbol_B.Color = Color
SetColorOfUnknownSymbol = LineSymbol_B
End If
End If
End If
End Function
Protected Overrides Sub OnUpdate()
Enabled = My.ArcMap.Application IsNot Nothing
End Sub
End Class