Geographic Information Systems Stack Exchange is a question and answer site for cartographers, geographers and GIS professionals. Join them; it only takes a minute:

Sign up
Here's how it works:
  1. Anybody can ask a question
  2. Anybody can answer
  3. The best answers are voted up and rise to the top

I am trying to override the drawing of a feature within a custom plugin data source. I believe this entails making a custom IFeatureRenderer.

However, the "renderer" I'd like to design would be 99% the same as a ClassBreaksRenderer, but with a custom Draw override.

What would be the simplest manner to be able to reuse the existing functionality of the ClassBreaksRenderer (including and especially the UI property pages) while still being able to provide a custom Draw implementation?

share|improve this question
up vote 3 down vote accepted

Since for feature renderers, it is the property page that is registered so that it appears in the UI (renderers themselves are not registered), your best bet is to implement your own property page and relay all (or most) of its calls to an GraduatedColorPropertyPage instance. This class is the property page for class breaks renderers.

Now, for the feature renderer, you have two options.

  1. You implement your own from scratch. You will need to implement most of the interfaces the ClassBreaksRenderer class does as the property page surely relies on them to be implemented.

  2. Again, similarly to the property page, you use composition. Create an instance of ClassBreaksRenderer and route all calls (on all of its interfaces) except possibly the Draw method to that inner instance.

It is clear that option 2 is way more convenient.

EDIT: For both classes, you need to pay attention to methods which return GUIDs or create object instances. Those methods are not routed to an inner instance since you need to return a different, correct GUIDs or instances for your classes. This is the case of:

  1. IRendererPropertyPage.ClassID, IRendererPropertyPage.RendererClassID, IPropertyPageContext.CreateCompatibleObject for the property page class.

  2. IPersistStream.GetClassID, IPersist.GetClassID for the renderer.

There is a cleaner way to do that, called COM aggregation. Query interfaces are pointed to the inner instance automatically so that you do not need to implement them on the outer instance (unless you want to override them). Also, COM aggregation ensures that should the author of the inner class add new interfaces in a future release, your outer class will support them as well. Unfortunately COM aggregation can be done only in C++, it's not (as far as I know) possible in .NET runtimes 1.1 or 2.0. There are some new features for custom COM interface querying (which should make COM aggregation possible) in .NET 4, but I have yet to see a working sample.

share|improve this answer
About the COM aggregation bit, here is an example from StackOverflow on using it in .NET 4. Not much use to ArcGIS developers yet, but at least MS isn't forgetting about COM. – blah238 Jul 27 '11 at 6:46
Yeah, we have discussed this with Kirk some time ago in context of custom features. See… – Petr Krebs Jul 27 '11 at 7:02
+1 For option 2, I wonder if there's some Visual Studio tool that would generate the code for this. Also, you might look at ILayerExtensionDraw if you want to decorate what OOTB Draw does. – Kirk Kuykendall Jul 27 '11 at 14:11
@Kirk, when you go to implement an interface in Visual Studio, there should be an option to automatically stub out its members -- is this what you meant? – blah238 Jul 27 '11 at 19:28
Well, I've gone through and done this (using method 2), and for some reason, it seems like the GraduatedColorPropertyPage will automatically create a new ClassBreaksRenderer that replaces mine, so this doesn't work. It works the first time through, but then the property page (via composition) "kills" the renderer I generate, which means my draw routine never gets called. – Reed Copsey Jul 29 '11 at 19:37

Your Answer


By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.