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"
));
}
}