WPF-对视图模型数据执行复制/粘贴与拖放时内存不足
我有一个WPF-对视图模型数据执行复制/粘贴与拖放时内存不足,wpf,mvvm,drag-and-drop,treeview,copy-paste,Wpf,Mvvm,Drag And Drop,Treeview,Copy Paste,我有一个TreeView,它提供拖放和复制/粘贴功能。我扩展了TreeViewItem,以提供该功能 拖放操作工作正常。树绑定到视图模型,并在treevieItem自定义类中启动拖动,例如: protected override void OnMouseMove(MouseEventArgs e) { // ... if (canDrag) { DragDrop.DoDragDrop(this, DataCo
TreeView
,它提供拖放和复制/粘贴功能。我扩展了TreeViewItem
,以提供该功能
拖放操作工作正常。树绑定到视图模型,并在treevieItem
自定义类中启动拖动,例如:
protected override void OnMouseMove(MouseEventArgs e)
{
// ...
if (canDrag)
{
DragDrop.DoDragDrop(this, DataContext, DragDropEffects.Copy);
e.Handled = true;
}
}
void CopyExecuted(object sender, ExecutedRoutedEventArgs e)
{
Clipboard.Clear();
Clipboard.SetData(DataContext.GetType().ToString(), DataContext);
}
该下降被启动,例如:
protected override void OnDrop(DragEventArgs e)
{
// ...
Paste(e.Data);
e.Handled = true;
}
void PasteExecuted(object sender, ExecutedRoutedEventArgs e)
{
Paste(Clipboard.GetDataObject());
}
它调用一个粘贴方法,该方法接收IDataObject
,例如:
protected void Paste(IDataObject data)
{
// ...
if (data.GetDataPresent(typeof(FooViewModel)) == true)
{
// process Foo drop
copiedFoo = data.GetData(typeof(FooViewModel)) as FooViewModel;
// ...
}
}
复制/粘贴操作的设置如下所示。在treevieItem
自定义类中启动复制,例如:
protected override void OnMouseMove(MouseEventArgs e)
{
// ...
if (canDrag)
{
DragDrop.DoDragDrop(this, DataContext, DragDropEffects.Copy);
e.Handled = true;
}
}
void CopyExecuted(object sender, ExecutedRoutedEventArgs e)
{
Clipboard.Clear();
Clipboard.SetData(DataContext.GetType().ToString(), DataContext);
}
将启动粘贴,例如:
protected override void OnDrop(DragEventArgs e)
{
// ...
Paste(e.Data);
e.Handled = true;
}
void PasteExecuted(object sender, ExecutedRoutedEventArgs e)
{
Paste(Clipboard.GetDataObject());
}
使用上面的IDataObject
调用相同的粘贴方法
问题:相同的粘贴方法在调用GetData()
时失败,内存不足,无法在从复制/粘贴操作调用时继续执行程序消息。我甚至将一个空的视图模型实例传递到剪贴板,同样的结果是内存不足
有一个已知的VS2010问题与此类似,解释道。我安装了该修补程序,但内存问题仍然存在
有什么想法吗?我是否应该以不同的方式与
剪贴板进行交互?谢谢 我以前遇到过这个问题,它与在剪贴板中存储对象有关。我不记得确切的原因,但我需要序列化我的对象,并将字节[]
存储在剪贴板中,而不是对象本身
我使用的代码如下所示:
写作:
byte[] data = SerializationHelpers.SerializeToBinary<TreeNodeBase>(
selectedTreeNode,
new Type[] { typeof(TreeNodeA), typeof(TreeNodeB),typeof(TreeNodeC)}
);
Clipboard.SetDataObject(data, true);
byte[]data=SerializationHelpers.SerializationToBinary(
选定的重节点,
新类型[]{typeof(TreeNodeA),typeof(TreeNodeB),typeof(TreeNodeC)}
);
剪贴板.SetDataObject(数据,真);
阅读:
IDataObject data = Clipboard.GetDataObject();
if (data.GetDataPresent(typeof(byte[])))
{
MyClass obj = SerializationHelpers.DeserializeFromBinary<TreeNodeBase>(
(byte[])data.GetData(typeof(byte[])),
new Type[] {typeof(TreeNodeA), typeof(TreeNodeB),typeof(TreeNodeC)}
);
}
IDataObject data=Clipboard.GetDataObject();
if(data.GetDataPresent(typeof(byte[]))
{
MyClass obj=SerializationHelpers.DeserializeFromBinary(
(byte[])data.GetData(typeof(byte[]),
新类型[]{typeof(TreeNodeA),typeof(TreeNodeB),typeof(TreeNodeC)}
);
}
序列化类
public static byte[] SerializeToBinary<T>(T obj, Type[] extraTypes)
{
if (obj == null)
return null;
using (MemoryStream ms = new MemoryStream())
{
DataContractSerializer dcs = new DataContractSerializer(typeof(T), extraTypes);
dcs.WriteObject(ms, obj);
return ms.ToArray();
}
}
public static T DeserializeFromBinary<T>(byte[] data, Type[] extraTypes)
{
if (data.Length == 0)
return default(T);
using (MemoryStream ms = new MemoryStream())
{
ms.Write(data, 0, data.Length);
ms.Seek(0, 0);
DataContractSerializer dcs = new DataContractSerializer(typeof(T), extraTypes);
return (T)dcs.ReadObject(ms);
}
}
publicstaticbyte[]SerializeToBinary(T obj,Type[]extractypes)
{
if(obj==null)
返回null;
使用(MemoryStream ms=new MemoryStream())
{
DataContractSerializer dcs=新的DataContractSerializer(typeof(T),extraTypes);
dcs.WriteObject(ms,obj);
返回ToArray女士();
}
}
公共静态T反序列化FromBinary(字节[]数据,类型[]外部类型)
{
如果(data.Length==0)
返回默认值(T);
使用(MemoryStream ms=new MemoryStream())
{
ms.Write(数据,0,数据长度);
Seek女士(0,0);
DataContractSerializer dcs=新的DataContractSerializer(typeof(T),extraTypes);
返回(T)dcs.ReadObject(ms);
}
}
您解决的VS2010问题是VS2010应用程序本身的问题。这是另外一件事……你真的应该把这种东西放到剪贴板上吗?@Paul,谢谢。视图模型占用的空间足够小,因此将其放入DataObject进行拖放似乎不是问题。数据对象的剪贴板处理是否更占用内存?我以前遇到过这个问题,我真的不记得是如何解决的。我相信这与在内存中存储一个对象有关,我想我最终序列化了这个对象,但我不是肯定的。@Rachel,谢谢。如果没有更简单的方法,我想尝试序列化视图模型并从剪贴板中获取文本。剪贴板意味着COM。您的ViewModel及其组件是否可见?如果我没有弄错的话,它也应该是可序列化的,或者可以通过值进行复制。+1感谢您提供了一种序列化方法,我可能会采用这种方法。这种方法的一个小问题是,我还需要将数据类型传递到剪贴板,因为不同的树节点具有不同的类型,可能会将其作为剪贴板文本传递?树节点是否继承自相同的基类型?如果是这样,您可以简单地将对象强制转换为基类型。如果在序列化/反序列化时包含基类型的任何子类型,应该不会有问题。是的,我有一个通用的基类型,并且可以传递一长串子类型。我现在的主要问题是(与我的模型类不同),我的视图模型类不是设计为可序列化的,所以需要做一些返工!