2012-04-22 74 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