我正在尝试从另一个线程访问 ListView 对象。我这样做的方式是为新线程创建一个临时 ListView,然后在填充新列表时每秒将这个临时 ListView 复制回原始列表。
我在复制 ListView 对象时遇到了困难。我环顾四周,找到了复制项目的方法,但我也需要列和结构也相同。
如果我只是这样做:
ListView lv_temp = lv_original
然后它通过引用复制它,我会得到更多的线程访问错误。
那么如何按值进行完整的克隆呢?
你想要做的是深拷贝列表,所以你可以使用这个扩展:
/// <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 上的源。如果这就是您想要的,请告诉我以提供更多详细信息。
您需要提供一个对象作为数据源。当您的数据源更新时,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);
更新
找到答案你如何绑定...。所以没有我最初假设的 DataSource 属性。