我想在线程中向DataGrid添加项目。
我有用户控件的查看模型:
public class Contact
{
public string Name { get; set; }
public string Phone { get; set; }
}
public class ContactGridViewModel
{
public ContactGridViewModel()
{
Items = new ObservableCollection<Contact>();
}
public ObservableCollection<Contact> Items { get; private set; }
public Dispatcher Dispatcher
{
get { return Dispatcher.CurrentDispatcher); }
}
private DispatcherOperation LastOperation { get; set; }
public void Update(IEnumerable<Contact> contacts)
{
if (LastOperation != null) LastOperation.Abort();
Items.Clear();
foreach (var item in contacts)
LastOperation = Dispatcher.BeginInvoke(
DispatcherPriority.Background,
new ParameterizedThreadStart(o => Items.Add(o))),
item);
}
}
有标记示例:
<!--DataContext="{Binding ContactGridViewModel}-->
<DataGrid ItemsSource="{Binding Items, Mode=OneWay}">
<DataGrid.Columns>
<DataGridTextColumn Header="Name" Binding="{Binding Path=Name}" />
<DataGridTextColumn Header="Phone" Binding="{Binding Path=Phone}" />
</DataGrid.Columns>
</DataGrid>
第二次执行Update方法后,如果没有完全添加第一个集合,DataGrid将包含第一个集合和完整第二个集合的一部分。
// contactList1 and contactList2 are IEnumerable<Contact> objects
Model.Update(contactList1);
Model.Update(contactList2);
我尝试中止DispatcherOperation,但它不会停止向Items属性添加联系人。
你能告诉我向DataGrid ItemsSource添加对象的正确方法吗?
答案 0 :(得分:2)
您应该收集列表中的所有DispatcherOpretations,然后将其全部中止。
public class ContactGridViewModel
{
public ContactGridViewModel()
{
Items = new ObservableCollection<Contact>();
LastOperations = new List<DispatcherOperation>();
}
public ObservableCollection<Contact> Items { get; private set; }
private ICollection<DispatcherOperation> LastOperations { get; set; }
public Dispatcher Dispatcher
{
get { return Dispatcher.CurrentDispatcher); }
}
private void StopUpdating()
{
foreach (var operation in LastOperations)
{
operation.Abort();
}
LastOperations.Clear();
}
public void Update(IEnumerable<Contact> contacts)
{
StopUpdating();
Items.Clear();
foreach (var item in contacts)
LastOperations.Add(Dispatcher.BeginInvoke(
DispatcherPriority.Background,
new ParameterizedThreadStart(o => Items.Add(item))),
item));
}
}
答案 1 :(得分:1)
在Update(contactList1)
方法中,您为contactList1中的每个项目开始Dispatcher.BeginInvoke()
,但如果您输入Update(contactList2)
,则只会在LastOperation中止一次,这不是完整的foreach而是单个Items.Add()
。
尝试这样的事情(未经测试):
public void Update(IEnumerable<Contact> contacts)
{
if (LastOperation != null) LastOperation.Abort();
Items.Clear();
LastOperation = Dispatcher.BeginInvoke(
DispatcherPriority.Background,
new ParameterizedThreadStart(o => { foreach (var item in o) Items.Add(item); }),
contacts);
}