如何在运行时将控件存入内存并在设计时粘贴到窗体?
问题解决步骤
1. 为mybutton类添加序列化特性
BinaryFormatter要求被序列化的类必须标记<Serializable()>, 你的类缺少这个关键特性,会导致序列化/反序列化失败。修改类定义:
<Serializable()> Friend Class mybutton Public Property Location As Point Public Property Size As Size Public Property BackColor As Color Public Property Text As String Public Sub New() End Sub Public Sub New(pb As Button) Location = pb.Location Size = pb.Size BackColor = pb.BackColor Text = pb.Text End Sub End Class
2. 修正序列化时的流位置
序列化完成后必须将MemoryStream的位置重置到起始处,否则后续读取流会从末尾开始,导致无有效数据:
formatter.Serialize(stream, button) stream.Position = 0 ' 取消注释并保留这行代码
3. 实现粘贴逻辑
你需要在窗体中添加处理粘贴的代码,才能将剪贴板中的自定义数据转换为可显示的按钮控件。示例如下:
步骤1:设置窗体KeyPreview=True,然后处理KeyDown事件
Private Sub Form1_KeyDown(sender As Object, e As KeyEventArgs) Handles MyBase.KeyDown If e.Control AndAlso e.KeyCode = Keys.V Then PasteMyButtonFromClipboard() End If End Sub
步骤2:编写粘贴处理函数
Private Sub PasteMyButtonFromClipboard() Dim dataObject As IDataObject = Clipboard.GetDataObject() If dataObject.GetDataPresent("MyButton") Then Using stream As MemoryStream = DirectCast(dataObject.GetData("MyButton"), MemoryStream) stream.Position = 0 Dim formatter As New BinaryFormatter() Dim myBtn As mybutton = DirectCast(formatter.Deserialize(stream), mybutton) ' 创建真正的WinForms按钮并添加到窗体 Dim newButton As New Button() newButton.Text = myBtn.Text newButton.Location = myBtn.Location newButton.Size = myBtn.Size newButton.BackColor = myBtn.BackColor Me.Controls.Add(newButton) End Using End If End Sub
4. 额外注意事项
- 确保序列化和反序列化使用的
mybutton类结构完全一致(包括命名空间、类名、属性定义),否则反序列化会报错。 - 若使用.NET Core/.NET 5+版本,
BinaryFormatter已被标记为过时,建议改用Newtonsoft.Json或System.Text.Json实现序列化:' 序列化示例(Newtonsoft.Json) Dim json As String = JsonConvert.SerializeObject(button) dataObject.SetData("MyButton", json) ' 反序列化示例 Dim json As String = DirectCast(dataObject.GetData("MyButton"), String) Dim myBtn As mybutton = JsonConvert.DeserializeObject(Of mybutton)(json)
内容的提问来源于stack exchange,提问作者user3172186
相关产品推荐
相关产品推荐

