ThinkGeo.com    |     Documentation    |     Premium Support

ZedGraph creation from a different thread

 Hi,


I would like to add ZedGraphs to the features within my Map, I have used the sample code with success and would like to implement the functionality within my own application. Here is the code I am using (based upon the sample code) :


The CreateZed() function is called after the features are retrieved from a database.


 private ZedGraphStyle CreateZed(WpfMap pMap)


{


ZedGraphStyle zed = new ZedGraphStyle();


zed.ZedGraphDrawing += ZedGraphStyle_ZedGraphDrawing;


return zed;


}




private delegate Bitmap ToUIThreadDelegate(WpfMap pMap, ZedGraphDrawingEventArgs e);


private void ZedGraphStyle_ZedGraphDrawing(object pSender, ZedGraphDrawingEventArgs pE)


{


pE.Bitmap = (Bitmap) Dispatcher.CurrentDispatcher.Invoke


(


new ToUIThreadDelegate(ZedGraphDrawing), new object[] { pE.Feature.Tag, pE }


);


}




private Bitmap ZedGraphDrawing(WpfMap pMap, ZedGraphDrawingEventArgs pE)


{


double scale = ExtentHelper.GetScale(pMap.CurrentExtent, (float) pMap.Width, GeographyUnit.DecimalDegree);


// Change the size of the graph based on the scale.  It will get bigger as you zoom in.


int graphHeight = Convert.ToInt32(100000000 / scale);


// After this, the code from the sample is pasted / used, nothing interesting.


}


My problem is that I need to access the Map I am currently building in one way or the other. I've tried to do so by adding a Tag to my Features with the WpfMap which is displayed. The reason I am trying to achieve this is that I would like the charts to be, as within the sample, zoom level dependent.


The Sample contained "Dispatcher.Invoke" yet this didn't work, so I added "Dispatcher.CurrentDispatcher" instead. I've also tried to access the WpfMap that is being created via the "map" parameter, to no avail.


I must say that the code is fully functional (e.g. graphs are being displayed over the features), if the "scale" variable is given a hardcoded value.


Since the delegate creates a new Thread, I immediately receive a "System.InvalidOperationException" Except, stating "The calling thread cannot access this object", since it resides in another thread. The same thing (obviously) happens when I try to store the WpfMap within my current class.


Is there a workaround ? The "Sender" Parameter from the EventHandler only points to the ZedGraphStyle Object created earlier. I am using ThinkGeo 4.5 Desktop WPF Edition, within a .NET 3.5 context.


Or is there another way to get the scale and implement a zoom level dependent graph scaling ?


Thank you in advance !



Cosmin,


I tried your code above and I encountered the different exceptions from you, here is the screen shot for my exception below:



 


The e.Feature.Tag is null in my application, I made the sample as the same as your code, I think maybe there are any else differences between us, your problem is an invalid operation exception.


So can you attach the whole solution to us so that we can encountered the same problem with you and look for any workarounds.


Thanks,


Scott,



 Hi,


 
I've investigated the matter further and I've found a resolution -- modifying the invoking Dispatcher from
 
pE.Bitmap = (Bitmap) Dispatcher.CurrentDispatcher.Invoke
 
to
 
pE.Bitmap = (Bitmap) mCurrentDispatcher.Invoke
 
where "mCurrentDispatcher" is :
 
// myMap is an instance of WpfMap
myMap.Dispatcher
 
That solved it, since the calling thread is the map's.
Turned out it was more of matter of WPF rather than ThinkGeo :-).
 
Thank you for your input !

Cosmin, 
  
 That’s great! If you encounter any more problems please let us know again, 
  
 Thanks, 
  
 Scott,