We are using the RadGridView with a VirtualQueryableCollectionView as Itemsource using WPF and EF.
This works great for paging and scrolling, however we can't figure out how to deal with the following situation:
- We sort the grid by a property, name for instance.
- Then, outside of the grid, the name property is altered
- Our viewmodel receives a message that the item has changed
What we want to do now, is to refresh the grid, with the current item still selected.
However, since the name has changed, we don't know the index that has to be queried to get the item with the id of the changed item.
So the question is: knowing the ID of an entity, how can you make VirtualQueryableCollectionView load the item with that ID into the grid?The same situation arises when we want to select a entity (with known id) that has been newly created outside of the viewmodel.
We use the following VirtualQueryableCollectionViewHelper to create the set the VirtualQueryableCollecitonView.
QueryGenerator(QueryableXenoxContext) returns an EntityQuery
This works great for paging and scrolling, however we can't figure out how to deal with the following situation:
- We sort the grid by a property, name for instance.
- Then, outside of the grid, the name property is altered
- Our viewmodel receives a message that the item has changed
What we want to do now, is to refresh the grid, with the current item still selected.
However, since the name has changed, we don't know the index that has to be queried to get the item with the id of the changed item.
So the question is: knowing the ID of an entity, how can you make VirtualQueryableCollectionView load the item with that ID into the grid?The same situation arises when we want to select a entity (with known id) that has been newly created outside of the viewmodel.
We use the following VirtualQueryableCollectionViewHelper to create the set the VirtualQueryableCollecitonView.
QueryGenerator(QueryableXenoxContext) returns an EntityQuery
public class VirtualQueryableCollectionViewHelper<T> where T : Entity{ public IEventAggregator EventAggregator { get; set; } public VirtualQueryableCollectionViewHelper(Func<QueryableXenoxContext, EntityQuery<T>> queryGenerator, queryableXenoxContext queryableXenoxContext, XenoxGridView gridView) { EventAggregator = ClientIocContainer.Instance.GetExportedValue<IEventAggregator>(); QueryGenerator = queryGenerator; QueryableXenoxContext = queryableXenoxContext; GridviewControl = gridView; DoNothing = i => { }; View = new VirtualQueryableCollectionView<T> { LoadSize = 30, VirtualItemCount = 100 }; View.ItemsLoading += (sender, args) => LoadInternal(args.StartIndex, args.ItemCount, DoNothing); View.FilterDescriptors.CollectionChanged += (sender, args) => LoadInternal(0, View.LoadSize, DoNothing); View.FilterDescriptors.ItemChanged += (sender, args) => LoadInternal(0, View.LoadSize, DoNothing); View.SortDescriptors.CollectionChanged += (sender, args) => LoadInternal(0, View.LoadSize, DoNothing); if (gridView == null) { ScrollIndexIntoView = DoNothing; } else { ScrollIndexIntoView = i => gridView.ScrollIndexIntoCenterOfView(i); } } public void Load(int currentIndex, int pageSize) { LoadInternal(currentIndex, pageSize, ScrollIndexIntoView); } public void Refresh(bool scrollToIndex = false, int currentIndex = 0) { var postLoadAction = scrollToIndex ? ScrollIndexIntoView : DoNothing; LoadInternal(currentIndex, View.LoadSize, postLoadAction); } public IEnumerable<T> GetAllCollectionItems() { return QueryableXenoxContext.Load(QueryGenerator(QueryableXenoxContext)).Entities; } private void LoadInternal(int currentIndex, int pageSize, Action<int> onLoaded) { if (currentIndex < 0) currentIndex = 0; //also load content above current item pageSize = pageSize*2; var loadStartIndex = currentIndex - pageSize / 2 < 0 ? 0 : currentIndex - pageSize / 2; var entityQuery = QueryGenerator(QueryableXenoxContext) .Sort(View.SortDescriptors) .Where(View.FilterDescriptors) .Skip(loadStartIndex) .Take(pageSize); entityQuery.IncludeTotalCount = true; try { QueryableXenoxContext.Load(entityQuery, LoadBehavior.RefreshCurrent, lo => { if (lo.TotalEntityCount != -1 && lo.TotalEntityCount != View.VirtualItemCount) { View.VirtualItemCount = lo.TotalEntityCount; } View.Load(loadStartIndex, lo.Entities); onLoaded(currentIndex); }, null); } catch (InvalidOperationException) { EventAggregator.Publish(new ErrorReportedEvent("Error loading items. Possible cause: too many items selected")); } }