Sarà un bug dell'oggetto
System.Windows.Forms.DataObject?
Dal principio: ho una
treeview che contiene oggetti di tipo System.Windows.Forms.TreeNode ed oggetti
di tipo treeNode che ereditano, naturalmente, dal primo tipo.
Quando parte un
Drag&Drop chiamo la DoDragDrop con il nodo in questione:
Me.DoDragDrop(e.Item, AllowDrag)
All'evento DragOver verifico la presenza di un oggetto di tipo
System.Windows.Forms.TreeNode in e.Data:
If e.Data.GetDataPresent(GetType(System.Windows.Forms.TreeNode)) Then
Purtroppo
questo metodo ritorna true SOLO nel caso che l'oggetto sia effettivamente di
tipo System.Windows.Forms.TreeNode e non se questo é un tipo da lì
ereditato!!!
Soluzioni?
Nulla, quindi mi armo di Reflector ed indago:
Innanzitutto
e.Data a parte l'interfaccia IDataObject é di tipo
System.Windows.Forms.DataObject il quale contiene un campo
privato che si chiama InnerData del tipo privato
System.Windows.Forms.DataObject.DataStore.
System.Windows.Forms.DataObject.DataStore
ha un campo privato di nome data e tipo HashTable.
All'interno di tale hashtable vengono immaginazzinati oggetti di tipo (privato ovviamente)
System.Windows.Forms.DataObject.DataStore.DataStoreEntry il
quale tipo contiene un campo (gioite: questo é publico! ) di nome data che contiene
effettivamente l'oggetto che abbiamo passato alla DoDragDrop.
Quindi, eccovi l'inguardabile soluzione:
Private Shared DataObject_innerDataFI As System.Reflection.FieldInfo = _
GetType(System.Windows.Forms.DataObject).GetField("innerData", Reflection.BindingFlags.NonPublic Or Reflection.BindingFlags.Instance)
Private Shared DataStoreType As System.Type = _
GetType(System.Windows.Forms.DataObject).GetNestedType("DataStore", Reflection.BindingFlags.NonPublic)
Private Shared DataStore_dataFI As System.Reflection.FieldInfo = _
DataStoreType.GetField("data", Reflection.BindingFlags.NonPublic Or Reflection.BindingFlags.Instance)
Private Shared DataStoreEntryType As System.Type = _
DataStoreType.GetNestedType("DataStore", Reflection.BindingFlags.NonPublic)
Private Shared DataStoreEntry_dataFI As System.Reflection.FieldInfo = _
DataStoreType.GetField("data", Reflection.BindingFlags.NonPublic Or Reflection.BindingFlags.Instance)
Protected Overridable Function GetData(ByVal Data As System.Windows.Forms.DataObject, ByVal type As System.Type) As Object
'System.Windows.Forms.DataStore é un tipo privato!
Dim DataStore As Object = DataObject_innerDataFI.GetValue(Data)
Dim hash As Hashtable = DirectCast(DataStore_dataFI.GetValue(DataStore), Hashtable)
For Each DI As System.Collections.DictionaryEntry In hash
Dim Value As Object = DataStoreEntry_dataFI.GetValue(DI.Value)
If type.IsInstanceOfType(Value) Then
Return Value
End If
Next DI
End Function
GetData vi ritornerà l'oggetto di tipo Type contenuto nel
DataObject passato!
...Ora me ne vado a casa a sciacquarmi gli occhi, buon weekend a tutti!!!