WPF - 使用视图模型数据执行复制/粘贴和拖放时,内存不足 [英] WPF - insufficient memory when doing copy/paste vs drag/drop with view model data

查看:351
本文介绍了WPF - 使用视图模型数据执行复制/粘贴和拖放时,内存不足的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个 TreeView ,提供拖放以及复制/粘贴功能。我扩展了 TreeViewItem 以提供该功能。

I have a TreeView that provides drag and drop as well as copy/paste functionality. I extended TreeViewItem to provide that functionality.

拖放可以正常工作。树被绑定到一个视图模型,拖动是在 TreeViewItem 自定义类中启动的,例如:

The drag and drop works fine. The tree is bound to a view model, and the drag is initiated in the TreeViewItem custom class such as:

    protected override void OnMouseMove(MouseEventArgs e)
    {
        // ...
        if (canDrag)
        {
            DragDrop.DoDragDrop(this, DataContext, DragDropEffects.Copy);
            e.Handled = true;
        }
    }

启动下拉列表,例如:

    protected override void OnDrop(DragEventArgs e)
    {
        // ...
        Paste(e.Data);
        e.Handled = true;
    }

它调用一个粘贴方法,它接收 IDataObject 如:

which calls a paste method that takes in an IDataObject such as:

    protected void Paste(IDataObject data)
    {
        // ...
        if (data.GetDataPresent(typeof(FooViewModel)) == true)
        {
            // process Foo drop
            copiedFoo = data.GetData(typeof(FooViewModel)) as FooViewModel;
            // ...
        }
    }

strong>复制/粘贴操作设置如下。该副本在 TreeViewItem 自定义类中启动,例如:

The copy/paste operation is set up as follows. The copy is initiated in the TreeViewItem custom class such as:

    void CopyExecuted(object sender, ExecutedRoutedEventArgs e)
    {
        Clipboard.Clear();
        Clipboard.SetData(DataContext.GetType().ToString(), DataContext);
    }

发起的粘贴如:

    void PasteExecuted(object sender, ExecutedRoutedEventArgs e)
    {
        Paste(Clipboard.GetDataObject());
    }

使用 IDataObject 以上。

问题:同样的粘贴方法在 GetData()通过复制/粘贴操作调用时,使用内存不足来继续执行程序消息。我甚至将一个空的视图模型实例传递到剪贴板,内存结果不足。

Issue: The same paste method fails at the GetData() call with an Insufficient memory to continue the execution of the program message when called from a copy/paste operation. I've even passed in an empty view model instance to the clipboard, with the same insufficient memory result.

已经有一个已知的VS2010类似的问题, a href =http://weblogs.asp.net/scottgu/archive/2010/06/27/patch-for-cut-copy-insufficient-memory-issue-with-vs2010.aspx =nofollow >此处。我安装了该修补程序,但内存问题仍然存在。

There has been a known VS2010 issue similar to this, explained here. I installed that hotfix, but the memory issue still persists.

任何想法?我应该与剪贴板的交互方式有所不同吗?谢谢!

Any ideas? Should I be interacting with the Clipboard differently? Thanks!

推荐答案

过去我遇到了这个问题,它与ClipBoard中存储一个对象有关。我不知道为什么,但是我需要序列化我的对象,并将字节[] 存储在剪贴板中,而不是对象本身。

I had this issue in the past, and it has to do with storing an object in the ClipBoard. I can't remember exactly why, but I needed to serialize my object and store the byte[] in the clipboard instead of the object itself.

我使用的代码看起来像这样:

The code I used looked something like this:

写作:

byte[] data = SerializationHelpers.SerializeToBinary<TreeNodeBase>(
    selectedTreeNode, 
    new Type[] { typeof(TreeNodeA), typeof(TreeNodeB),typeof(TreeNodeC)}
);

Clipboard.SetDataObject(data, true);

阅读:

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)}
    );
}

序列化类

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);
    }
}

这篇关于WPF - 使用视图模型数据执行复制/粘贴和拖放时,内存不足的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆