2012-04-22 75 views
0

我想从另一个线程访问一个ListView对象。我这样做的方式是为新线程创建一个临时ListView,然后在新列表被填充时将该临时ListView复制回原来的每一秒。将ListView复制到ListView - C#.NET 2.0

虽然我很难复制ListView对象。我环顾四周,找到了复制项目的方法,但我也需要列和结构也一样。

如果我简单地做:

ListView lv_temp = lv_original

然后将其复制它的参考,我会得到更多的线程访问错误。

那么我该如何做一个完整的克隆呢?

+3

只是不。只在线程中创建数据。填充它,比如说一个List <>。只在UI线程上填充ListView。 BackgroundWorker使其变得简单。 – 2012-04-22 17:39:23

+0

是的,@Hans说了什么。必须使用适当的数据源。 – IAbstract 2012-04-22 17:54:32

+0

这就是我所做的。我只想复制整个ListView,因为结构已经存在。我刚刚创建了一个具有相同列的新结构,然后将其逐行地复制到实际的结构中。 – CJxD 2012-05-02 07:53:03

回答

1

你想要做什么是深拷贝名单,所以你可以使用这个扩展:

/// <summary> 
/// Reference Article http://www.codeproject.com/KB/tips/SerializedObjectCloner.aspx 
/// 
/// Provides a method for performing a deep copy of an object. 
/// Binary Serialization is used to perform the copy. 
/// </summary> 

public static class ObjectCopier 
{ 
    /// <summary> 
    /// Perform a deep Copy of the object. 
    /// </summary> 
    /// <typeparam name="T">The type of object being copied.</typeparam> 
    /// <param name="source">The object instance to copy.</param> 
    /// <returns>The copied object.</returns> 
    public static T Clone<T>(T source) 
    { 
     if (!typeof(T).IsSerializable) 
     { 
      throw new ArgumentException("The type must be serializable.", "source"); 
     } 

     // Don't serialize a null object, simply return the default for that object 
     if (Object.ReferenceEquals(source, null)) 
     { 
      return default(T); 
     } 

     IFormatter formatter = new BinaryFormatter(); 
     Stream stream = new MemoryStream(); 
     using (stream) 
     { 
      formatter.Serialize(stream, source); 
      stream.Seek(0, SeekOrigin.Begin); 
      return (T)formatter.Deserialize(stream); 
     } 
    } 
}  

现在,我可能会问你为什么这样做,你为什么不通过名单另一个线程和多数民众赞成在所有(鉴于你修改它回来)。如果它是一个UI控件(可能是我看到的),那么可以使用背景ItemsSource(来自其他线程),然后使用Dispatcher在UI上将其用作源。如果这就是你想让我知道提供更多细节。

+0

好的解决方案 - 但是我会首先尝试一下源代码方法。这种方式需要在我的参考书目中增加另一个来源。 – CJxD 2012-04-22 17:51:26

+0

当然,这是我在第二段提到的解决方案(不要解释)。祝你好运:) – 2012-04-22 17:53:58

+0

我可能是错的,但我认为这是远离OP是什么*实际*试图实现 - 国际海事组织,问题是*“如何更新我的列表视图时,线程异常“* – IAbstract 2012-04-22 17:59:17

1

您需要提供一个对象作为数据源。当你的数据源被更新时,UI控件被更新。否则,如果碰上线程问题,使用的SynchronizationContext.Current,并分配给sync字段成员,则:

// since I believe you don't have lambdas in .net 2.0 I'll try to write this out proper 
    // although it is untested, but I hope you get the idea 
    sync.Send(new SendOrPostCallback(SendCallBack), stateObject); 

    void SendCallBack(object state) { 
    // perform UI tasks here 
    } 

SynchronizationContext在为新的.NET 2.0

...再次,这是未经测试,但是我必须开始的地方。 (?)正如顺便说一句,在.NET 3.0到现在,我们写:

sync.Send((state) => { 
    // perform UI tasks here 
    }, stateObject); 

更新
找到答案How do you bind ...。所以没有我最初设想的DataSource属性。

+0

看起来很整齐。我会看看它是否有效。它必须可以用我的Quicksort函数进行排序 - 只要它是可以分离的,我应该没问题。否则,我需要像ListView对象那样创建一个比较器。 – CJxD 2012-04-22 17:49:55

+0

你应该为你的listview创建一个数据源。然后你可以实现你想要的任何行为。 – IAbstract 2012-04-22 17:52:42

+0

此答案或其他答案无用。尝试将数据源强制到ListView中是不值得的,所以我放弃并复制了列的列,行列。 – CJxD 2012-04-24 22:23:52