ThinkGeo.com    |     Documentation    |     Premium Support

Layer class does not implement INotifyPropertyChanged?

 Guys, 


I am surprised that your Layer base class does not implement the INotifyPropertyChanged event.  Can you please propose a clean way for me to notify my view model that a layer's visibility has changed so that the map can be refreshed?  I was relying on this event being fired.


TIA,


klaus



Klaus, 
  
   Did you want that on just the Layer?  The reason I ask is that the Layer contain a bunch of other classes such as zoom levels which contain styles etc…  How does the INotifyPropertyChange work for these nested objects?  For example would you want an event to trigger on the layer if someone changes a style of the layer that is burried like Layer.ZoomLevelSet.ZoomLevel1.DefaultAreaStyle.Pen = xxx?  I am just curious how this works or does the event only raise when a direct property of the Layer change such as IsVisible?  I want to understand this to make sure we go about this in the right way. 
  
 David

 David, thanks for the quick response.  I now understand the reason why this interface is not implemented.  Even though a layer contains a bunch of nested objects, it would still be a good idea to have this event fired for simple or frequently used properties such as layer visibility, name etc.  


 



Hi Klaus, 
  
 It’s a good idea to have INotifyPropertyChanged implemented and you can easily use Binding etc. But we don’t recommend to Binding the properties on layer; Layer object nests a bunch of objects; if you use binding or trigger the property changed event every time when simple or frequently used properties changed, the map or its containing overlay needs to be refreshed; which really affects the performance if this happens frequently. Because all the properties and its nested object on the layer makes an image refreshing once and once again on the application; it’s a little different from binding to a ListView. So we didn’t have this interface implemented because we don’t recommend to do this currently. 
  
 Hope it makes sense. Also, you can show us your requirement, so that we’ll try to think about a workaround for you temporary. 
  
 Thanks for your idea and let me know if you have more queries. 
 Howard

I too am for implementing INotifyPropertyChanged...  I havea use case where this would be exremely useful:


1) Creating a tree of overlays/layers which allows the user to specify which layers are visible.  In my use case, other controls can add to the collection of overlays and layers, so the layer visibility tree must be notified of the change.



Hi Ryan, 
  
 As I mentioned above, it costs the performance a lot if you refresh the map quite frequently. Also as David said, if we implement this interface on the Layer, we need consider to implement this interface for all of our other classes in all our product line. So I think we won’t do it in the near future. Sorry for the inconvenience. 
  
 On the other hand, if you want binding the source to the overlay, I recommend writing a LayerWrapper which implements INotifyPropertyChanged interface. In the wrapper, we have two properties that are Layer object and IsVisible. And binding this collection to the tree instead. 
  
 Please try it and let me know if you have any queries. 
  
 Thanks, 
 Howard

I completely understand where Howard is coming from in regards to performance.  MapSuite performance is very good and should not be compromised by allowing such  easy constructus.    What Howard has proposed is exactly what we have done.  What we have is a generic Table of Contents control that will work with any GIS vendor. 


The nodes that make up the table of contents is a thin wrapper around what each GIS vendor defines as a layer.  This LayerTocItem model which defines a TLayer property, an IsVisible and others that allow me to save map state, implements INotifyPropertyChanged and fires an event when the layer's IsVisible property changes.  


 





 



Hi Klaus, 
  
 Thank you so much for sharing your idea and it’s pretty good. 
  
 Thanks, 
 Howard

I’ve created my own Overlay extending from LayerOverlay which implements INotifyPropertyChanged.  I listen to the Layers.Added and Layers.Removed events, at which point I fire off the PropertyChanged event.  The problem is, when my list of layers goes to look at the list, it sees that it is the same reference and therefore does not update the list with the newly added layer information. 
  
 Then I decided just to create my own Overlay which has Layers as an ObservableCollection.  My only problem with this is I am unsure how to implement the DrawCore method.  I was just going to iterate through each of the layers and call the draw method on it, but I noticed the overlay DrawCore method doesn’t have a canvas, and I am unsure where or how that is created. 
  
 So my question is either how can I solve my problem using the first method OR how do I implement the the DrawCore function of an overlay to draw each layer in it. 
  
 Thanks in advance, 
 .Ryan.

Best thing is to just create a class that implements INotifyPropertyChanged and have two properties: TLayer and TOverlay.  Then fire your event when IsVisible of the overlay changes.  This is what I have done.  I would not attempt to override DrawCore if I were you.



Hi Ryan,



We did some research on our GeoCollection and we actually can implement the INotifyCollectionChanged interface; so that you can binding it without rewriting LayerOverlay. Please get the latest daily build 4.0.87.0 tomorrow and try the attached sample.



Thanks and let us know if you have more queries.



Thanks,

Howard



Post7888.zip (8.75 KB)

Thanks Howard, this worked perfectly.


.Ryan.



Hi Ryan, 
  
 Great; just feel free to let us know if you have more queries. 
  
 Thanks, 
 Howard