У меня есть DataGrid, связанный с DataGridCollectionView, который использует Observable Collection. Коллекция содержит около 650 предметов с 20 колонками. Каждые 60 секунд получен новый набор данных. Эти данные сравниваются с существующей коллекцией, а затем добавляются, удаляются и обновляются по мере необходимости. Для обновления я делаю следующее:При обновлении элементов коллекции для DataGrid Асинхронно, почему данные исчезают?
private async void LoadData()
{
await RefreshData(TimeSpan.FromSeconds(100), cts.Token);
}
private async Task RefreshData(TimeSpan interval, CancellationToken token)
{
// Get the writable properties for the ContingencyViewModel
var writableProperties = typeof(ContingencyViewModel).GetProperties(BindingFlags.Instance | BindingFlags.Public)
.Where(p => p.CanWrite);
while (!token.IsCancellationRequested)
{
var list = viewModel.Items;
var cvs = GetItems(); // Service call that gets the updated collection
var existingIds = list.Select(s => s.UniqueId).Distinct().ToList();
var sourceIds = cvs.Select(s => s.UniqueId).Distinct().ToList();
var toAdd = sourceIds.Except(existingIds).ToList();
var toRemove = existingIds.Except(sourceIds).ToList();
var toUpdate = existingIds.Intersect(sourceIds).ToList();
var itemsToAdd = cvs.Where(x => toAdd.Contains(x.UniqueId)).ToList();
var itemsToRemove = list.Where(x => toRemove.Contains(x.UniqueId)).ToList();
var itemsToUpdate = list.Where(x => toUpdate.Contains(x.UniqueId)).ToList();
// Add new items
foreach (ItemViewModel item in itemsToAdd)
{
list.Add(item);
}
// Remove dropped items
foreach (ItemViewModel item in itemsToRemove)
{
list.Remove(item);
}
// Update existing items
foreach (ItemViewModel item in itemsToUpdate)
{
// Get a reference to the Updated Item
var source = cvs.First(x => x.UniqueId == item.UniqueId);
// This works but locks the UI for a little bit
this.UpdateItem<ItemViewModel>(source, item, writableProperties);
// This also works but all the results in my grid disappear when I scroll or resize screen. To get them back I have to actually Expand and Collapse groups.
/*
Action d = delegate()
{
this.UpdateItem<ItemViewModel>(source, item, writableProperties);
};
Dispatcher.CurrentDispatcher.InvokeAsync(d, DispatcherPriority.Normal, token);
*/
}
if (token.IsCancellationRequested)
token.ThrowIfCancellationRequested();
if (interval > TimeSpan.Zero)
await Task.Delay(interval, token);
}
}
private void UpdateItem<T>(T source, T target, IEnumerable<PropertyInfo> properties)
{
foreach (var p in properties)
{
var value = p.GetValue(source);
p.SetValue(target, value);
}
}
Двигается прямо обновление лаги интерфейса, как я ожидал, однако пытаюсь сделать это из другого потока, кажется, вызывают данные исчезает, когда вы прокрутку или изменить размер окна. Я исчезаю, я имею в виду, что строки есть, но они пусты. Единственный способ вернуть его - это свернуть и развернуть группу. Я даже попытался добавить обновления для источника данных (что кажется мне плохой идеей, потому что оно будет вызвано после каждого обновления поля).
Почему данные исчезают при обновлении Async? Есть ли лучший или более подходящий способ сделать эти обновления для элементов, привязанных к datagrid?
Вы должны назвать свою логику обновления из потока пользовательского интерфейса. Попробуйте 'Dispatcher.BeginInvoke (youraction)', когда вы обновляете событие async. – nakiya