Conversion from the COM version of DicomObjects to the .NET version
Conversion of a DicomObjects ActiveX/COM project to .NET looks initially daunting, but in fact is quite simple, and for those using any of the complicated ActionComplete/ActionUpdate mechanisms and asynchronous DicomConnection objects will find that the resulting code is lot simpler and easier to maintain after conversion. As ever, we are happy to help with any conversion issues.
Threading Model
The .NET version is free-threaded so all the events fire on their own threads, rather than being marshalled back onto the main thread. In general, this hugely simplifies programming, but care needs to be taken to keep objects and collections synchronised. The effects of this are different for SCUs and SCPs:
SCUs
if you wish to initiate background tasks, simply use the standard .NET thread procedures to start a worker thread etc. There is no need in the .NET version to tie DicomConnection objects to DicomViewer or DicomServer objects (as there was in COM) simply to provide an attachment point for completion events
SCPs
It is here that the benefit really shows - each InstanceReceived (renamed version of ImageReceived/ImageReceivedAsync) is independent of others, so you can do slow blocking operations such as writing out files, sending to a C-MOVE recipient etc. without needing to worry about tying up the main application thread.
DataSet is now an explicit property of a DicomImage
This makes the relationship a lot clearer. DicomImage.DataSet contains all the intrinsic attributes of the DicomImage object which may be accessed via the Indexer, but contain no other information. A DicomImage on the other hand holds transient items such a zooming, flips, windowing etc.
Objects are no longer “cloned” implicitly, when added to collections
So for instance, the same DicomImage can be present in multiple DicomImageCollection Objects, and the same is true of labels. This is a simpler model, but means that an extra parameter is now needed for many methods (e.g. label ROI functions) as the label no longer has a “hidden” owner image property.
All collections have been renamed
This is in accordance with standard .NET best practice:
The DicomImages object has been renamed DicomImageCollection and DicomDataSets has been renamed DicomDataSetCollection
The same applies to collections of labels, connections etc.
The exception is the DicomAttributes collection, which has been removed altogether, as a collection of Attributes is identical in the .NET version to a DicomDataSet, so you can now use that wherever you would have used the Attributes property of a dataset (or image) in the COM version.
Also, as it only now represents a single Association at a time, the COM DicomConnection has been renamed DicomAssociation
All collections are now Zero-Based
Unlike COM version of DicomObjects, where Collections are 1 based, the new .NET version has all arrays and most of the collections 0 based.
Exceptions are where 1-based numbering is the “norm” in DICOM - i.e.:
- The DicomContextCollection, where indices are the context IDs of the presentation contexts - i.e.1,3,5,7 (as in COM)
- In keeping with DICOM normal practice, Frame numbers start from 1.
- Indexed values of the DicomAttribute object (individual items where VM >1) are still numbered from 1, again in keeping with DICOM Standard conventions
All DicomGlobal methods and properties are now static
Most of the methods that where previously available through the DicomGlobal object are still present in the DicomObjects.NET DicomGlobal object. The main difference in the .NET version is that they are all now static members, so you no longer have to create an instance of a DicomGlobal object in oder to be able to access them.
DicomViewer Object has NO networking functionalities
As the result of code simplification, DicomViewer object now has no networking functionalities as they should only belong to the DicomServer object.
No real registry settings in DicomObjects.NET
Real registry settings are not required as all settings are kept in an internal hash table. Check Registry Values for all registry settings in DicomObjects.
DicomConnection now called DicomAssociation
DicomConnection is a confusing name when talking about networking, so we decided to give it a clearer name, DicomAssociation.
Object Specific Changes
DicomImage Differences
The biggest simplification has been using the native .NET matrix object to reflect any image->screen transformations. It is available in multiple overloads for screen and other purposes. The other major change is that a DicomImage no longer has a specific connection to any one DicomImageCollection and therefore it can be present in many different DicomViewers
Also, there are now several direct constructors (e.g. for reading from a file) - there is no longer a need to create a Collection merely to read a file.
Replaced Properties and Methods:
- ActualZoom, ActualScrollX & ActualScrollY
- Matrix (lots of overloads for different situations)
- WriteFile, WriteArray, WriteStream & WriteMemory
- overloads of Write
Note that the matrix object unlike the old ActualZoom accounts for non-square pixels by having different values for the X and Y scaling. In order to get a value compatible with the Zoom property, use DicomGlobal.Zoom(Matrix) to extract the minimum scaling value.
DicomLabel Differences
The number of properties has been reduced markedly, mainly by using native .NET objects, so here are a few conversion pointers for specific COM properties:
- Top, Left, Width & Height
- Area
- Transparent, BackStyle & BackColour
- Brush
- ForeColour, LineWidth & LineStyle
- Pen & (for text) TextBrush
- Font, FontName & FontSize
- Font
- ImageTied & ScaleWithCell
- ScaleMode
- Alignment
- StringFormat.Alignment.(near, center, far) & StringFormat.LineAlignment.(near, center, far)
DicomGlobal Differences
- Version
- AssemblyVersion & FileVersion
- DirectionStrings
- DirectionStrings, now an array of 6 strings