Использование подкласса DataObject в качестве буфера обмена DataObject
Когда я попробую следующее, результаты будут неожиданными. Любые идеи будут оценены по достоинству!
Class DataObjectSub
Inherits DataObject
End Class
Sub Test()
Dim myObject = New DataObjectSub
myObject.SetData("Test")
Clipboard.SetDataObject(myObject)
Dim myRetrievedObject As IDataObject = Clipboard.GetDataObject
Console.Write(myRetrievedObject.GetType.ToString)
Dim myRetrievedObject2=TryCast(Clipboard.GetDataObject,DataObjectSub)
End Sub
myRetrievedObject2 - это ничто
Выходные данные оператора Write: "System.Windows.Forms.DataObject". Разве это не должно быть "DataObjectSub"? Я что-то упускаю из виду?
Отредактировано по запросу:
В случае операций перетаскивания, этот DataObject (реализующий iDataObject) снова используется, можно сделать это:
Sub TestDragDrop
Dim myObject as iDataObject=new DataObjectSub
someControl.DoDragDrop(myObject, myAllowedEffects)
End Sub
Позже... в обработчике события DragOver:
Sub anotherControl_DragOver(sender as object, e as DragEventArgs)
Dim myRetrievedObject1 as DataObjectSub = TryCast(e.Data, DataObjectSub)
Dim myRetrievedObject2 as IDataObject = e.Data
End Sub
работает хорошо, и myRetrievedObject1 и myRetrievedObject2 не являются ничем. Типы обоих извлеченных объектов: DataObjectSub.
Спасибо за любые идеи и терпение!:)
1 ответ
Это не неожиданное поведение. Clipboard.GetDataObject
просто хранит данные в Clipboard
(как указано в MSDN) и его тип DataObject
(как указано в вашем коде). Когда вы проверяете его тип, не имеет значения, является ли входная переменная DataObject
или любой другой тип (поддерживается GetDataObject
). Имейте в виду, что GetDataObject
является методом, возвращаемое значение которого не должно следовать правилам назначения по умолчанию (т. е. его вызов не вызывает тех же эффектов, что и назначение String
переменная к Object
переменная, например).
Этот код:
Dim myString As String = "Test"
Clipboard.SetDataObject(myString)
Dim myRetrievedObject As IDataObject = Clipboard.GetDataObject
Console.Write(myRetrievedObject.GetType.ToString)
выводит точно такой же результат, как и ваш код. myRetrievedObject.GetType.ToString
просто проверяет тип GetDataObject
, который всегда DataObject
,
ОБНОВИТЬ
После нашего обсуждения я хочу уточнить, что Clipboard.GetDataObject
возвращает IDataObject
переменная (интерфейс DataObject
, не другого типа). Пример кода, чтобы понять все это:
Dim myRetrievedObject1 As IDataObject = Clipboard.GetDataObject
Dim myRetrievedObject2 As DataObject = New DataObject(Clipboard.GetDataObject)
Dim myRetrievedObject3 As DataObject = DirectCast(Clipboard.GetDataObject, DataObject)
Dim test4 As DataObject = New DataObject
If (TypeOf myRetrievedObject1 Is DataObject AndAlso TypeOf myRetrievedObject2 Is DataObject AndAlso TypeOf myRetrievedObject3 Is DataObject AndAlso TypeOf test4 Is DataObject) Then
'Condition is met
End If
If (TypeOf myRetrievedObject1 Is IDataObject AndAlso TypeOf myRetrievedObject2 Is IDataObject AndAlso TypeOf myRetrievedObject3 Is IDataObject AndAlso TypeOf test4 Is IDataObject) Then
'Condition is met
End If
Как вы можете видеть (два условия выполнены, что означает, что все переменные имеют тип DataObject
а также IDataObject
в то же время), отношения DataObject
/ IDataObject
не похож на тот, что между двумя разными типами. На самом деле, как показано myRetrievedObject3
кастинг - это просто формальное требование (я кастую DataObject
переменная к DataObject
!). DataObject
/ IDataObject
в основном две стороны одной медали (которая называется DataObject
) Это подразумевает, что условие ниже верно:
Dim Type1 As String = myRetrievedObject1.GetType().ToString()
Dim Type2 As String = myRetrievedObject2.GetType().ToString()
Dim Type3 As String = myRetrievedObject3.GetType().ToString()
Dim Type4 As String = test4.GetType().ToString()
If (Type1 = Type2 AndAlso Type1 = Type3 AndAlso Type1 = Type4 AndAlso Type1 = GetType(DataObject).ToString) Then
'Condition is met
End If
То есть имя типа для обоих DataObject
а также IDataObject
переменные DataObject
(или, точнее: System.Windows.Forms.DataObject
).