Vb.net 使用子类数据对象作为剪贴板数据对象

Vb.net 使用子类数据对象作为剪贴板数据对象,vb.net,clipboard,idataobject,Vb.net,Clipboard,Idataobject,当我尝试以下方法时,结果出乎意料。任何想法都将不胜感激 Class DataObjectSub Inherits DataObject End Class Sub Test() Dim myObject = New DataObjectSub myObject.SetData("Test") Clipboard.SetDataObject(myObject) Dim myRetrie

当我尝试以下方法时,结果出乎意料。任何想法都将不胜感激

    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”吗?我错过了什么明显的东西吗

按要求编辑:

在拖放操作的情况下,再次使用该数据对象(实现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


谢谢你的建议和耐心!:)

这不是意外的行为<代码>剪贴板。GetDataObject只将数据存储在
剪贴板
(由引用)中,其类型为
数据对象
(由您的代码引用)。检查其类型时,输入变量是
DataObject
还是任何其他类型(由
GetDataObject
支持)都是无关的。请记住,
GetDataObject
是一种方法,其返回值不需要遵循默认的赋值规则(例如,调用它不会产生与将
字符串
变量赋值给
对象
变量相同的效果)

此代码:

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
变量(数据对象的接口,而不是其他类型)。理解所有这些的示例代码:

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
)。

这不是意外行为<代码>剪贴板。GetDataObject只将数据存储在
剪贴板
(由引用)中,其类型为
数据对象
(由您的代码引用)。检查其类型时,输入变量是
DataObject
还是任何其他类型(由
GetDataObject
支持)都是无关的。请记住,
GetDataObject
是一种方法,其返回值不需要遵循默认的赋值规则(例如,调用它不会产生与将
字符串
变量赋值给
对象
变量相同的效果)

此代码:

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
变量(数据对象的接口,而不是其他类型)。理解所有这些的示例代码:

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
)。

谢谢您的回复!我的困惑如下:MSDN(您提供的链接)声明GetDataObject的返回对象是iDataObject(而不是DataObject)。如果尝试:Dim myObject as DataObject=Clipboard.GetDataObject,则会出现隐式转换错误,因为iDataObject无法隐式转换为DataObject。如果MS希望GetDataObject的返回值是DataObject,为什么该方法返回iDataObject?(附带说明,DragDrop操作中使用的iDataObject接受子类数据对象(例如DataObjectSub)并与之配合使用)。感谢您的回复!我的困惑如下:MSDN(您提供的链接)声明GetDataObject的返回对象是iDataObject(而不是DataObject)。如果尝试:Dim myObject as DataObject=Clipboard.GetDataObject,则会出现隐式转换错误,因为iDataObject无法隐式转换为DataObject。如果MS希望GetDataObject的返回值是DataObject,为什么该方法返回iDataObject?(附带说明,DragDrop操作中使用的iDataObject接受子类数据对象(例如DataObjectSub),并且可以很好地使用它)。