I need to be load a pivot grid without blocking my UI. I am using:
ExposureGrid.DataSource.DeferredLayoutUpdate = true;ExposureGrid.DataSource.LoadSchemaCompleted += (s, e) => { ViewModel.LoadingData = false; }; ExposureGrid.DataSource.LoadSchemaAsync(); ExposureGrid.DataSource.DeferredLayoutUpdate = false;
Of course, LoadSchemaCompleted never fires.
Hello Sam,
The LoadSchemaCompleted event is fired once only. If you already have assigned your data source instance to serve as data source of pivot grid or data selector, LoadSchemaAsync() is automatically called for the data source when LayoutUpdated event is fired.
Could you specify what kind of data source you have?
Thanks.Plamen.
I am using flat data source. What is the suggested pattern for loading a pivot grid async? Is there an example you can direct me too?
Thanks,
Sam
Hi Sam,
Could you refer us to the point where the UI is blocked, when specific method is called or property is set.
Hello Plamen,
Here is the code that is blocking.Refresh is a method on my view that refreshes the xampivot grid.XAMPivotFilterHelper is a helper class that contains some utility methods, one of which is FilterOption.This method (FilterOption) is called several times by Refesh to set default filter options on the xampivot grid. Its very slow!
private void Refresh() { ViewModel.LoadingData = true; _mre = new ManualResetEvent(false);
ExposureGrid.DataSource.DeferredLayoutUpdate = true; if (ExposureGrid.DataSource.Filters.Count > 0) ExposureGrid.DataSource.Filters.Clear(); FilterHelper = new XAMPivotFilterHelper<ExposureItem> { FlatDataSource = ((FlatDataSource)ExposureGrid.DataSource) }; FilterHelper.FlatDataSource.ItemsSource = ViewModel.ExposureItems;
ExposureGrid.DataSource.Filters.Add(ExposureGrid.DataSource.CreateFilterViewModel( ExposureGrid.DataSource.Cube.Dimensions["PM_Name"].Hierarchies.First()));
ExposureGrid.DataSource.Filters.Add(ExposureGrid.DataSource.CreateFilterViewModel( ExposureGrid.DataSource.Cube.Dimensions["DeliveryDate"].Hierarchies.First()));
FilterHelper.FlatDataSource.HierarchyDescriptors.Where(x => x.HierarchyName == "Collateral") .Single().LevelDescriptors[1].OrderByKeyExpression = (Expression<Func<ExposureItem, string>>) (x => x.Collateral);
FilterHelper.FlatDataSource.HierarchyDescriptors.Where(x => x.HierarchyName == "Type") .Single().LevelDescriptors[1].OrderByKeyExpression = (Expression<Func<ExposureItem, string>>)(x => x.Type);
FilterHelper.FlatDataSource.HierarchyDescriptors.Where(x => x.HierarchyName == "Coupon") .Single().LevelDescriptors[1].OrderByKeyExpression = (Expression<Func<ExposureItem, decimal>>)(x => x.Coupon);
FilterHelper.FlatDataSource.HierarchyDescriptors.Where(x => x.HierarchyName == "AcctNo") .Single().LevelDescriptors[1].OrderByKeyExpression = (Expression<Func<ExposureItem, decimal>>)(x => x.AcctNo);
FilterHelper.FilterOption("DeliveryDate", "All", false); // Slow!!! FilterHelper.FilterOption("DeliveryDate", "N/A", true); // Slow!!! OnDeliveryChanged(this, new EventArgs()); // Slow!!! OnPMFilterChanged(this, new EventArgs()); // Slow!!! IFilterViewModel fvm = FilterHelper.GetFilterViewModel("Collateral"); fvm.LoadFilterMembersCompleted += (s, e) => _mre.Set(); foreach (Infragistics.Olap.Data.IFilterMember member in fvm.FilterMembers) FilterHelper.ExpandHierarchy(member, true); fvm = FilterHelper.GetFilterViewModel("Type"); fvm.LoadFilterMembersCompleted += (s, e) => _mre.Set();
foreach (Infragistics.Olap.Data.IFilterMember member in fvm.FilterMembers) FilterHelper.ExpandHierarchy(member, true);
ExposureGrid.DataSource.ResultChanged += FilterHelper.HierarchyChanged; ExposureGrid.DataSource.DeferredLayoutUpdate = false; ViewModel.LoadingData = false; }
public class XAMPivotFilterHelper<T> { public FlatDataSource FlatDataSource { get; set; } public List<T> Data { get; set; } private ManualResetEvent _mre;
public void SetFilter(IFilterMember filter, string value, bool set) { _mre = new ManualResetEvent(false);
if (filter.Caption == value) { filter.IsSelected = set; }
/* expand the filter if closed */ if (!filter.IsExpanded) { filter.IsExpanded = true; _mre.WaitOne(); }
foreach (var child in filter.FilterMembers) { SetFilter(child, value, set); } }
public IFilterViewModel GetFilterViewModel(string caption) { foreach (var filter in FlatDataSource.Filters) { if (filter.Caption == caption) { return (IFilterViewModel)filter; } }
foreach (var row in FlatDataSource.Rows) { if (row.Caption == caption) { return (IFilterViewModel)row; } }
foreach (var column in FlatDataSource.Columns) { if (column.Caption == caption) { return (IFilterViewModel)column; } }
return null; }
public void ExpandHierarchy(IFilterMember filter, bool value) { _mre = new ManualResetEvent(false);
if (filter.IsExpanded != value) { filter.IsExpanded = value; }
if (filter.FilterMembers == null) { _mre.WaitOne(); }
foreach (var child in filter.FilterMembers) { ExpandHierarchy(child, value); } }
public void FilterOption(string tag, string value, bool set = true) { IFilterViewModel fvm = GetFilterViewModel(tag);
fvm.LoadFilterMembersCompleted += (s, e) => _mre.Set();
if (fvm.FilterMembers != null) { foreach (var filter in fvm.FilterMembers) { SetFilter(filter, value, set); } }
fvm.CommitChanges(); }
public void OnResultChanged(object sender, AsyncCompletedEventArgs e) { Data = new List<T>();
List<int> indices = FlatDataSource.GetCellItemsIndexes( FlatDataSource.Result.Cells[FlatDataSource.Result.Cells.GetUpperBound(0), FlatDataSource.Result.Cells.GetUpperBound(1)]); foreach (int index in indices) Data.Add(((T)FlatDataSource.GetRecord(index))); }
public void HierarchyChanged(object sender, AsyncCompletedEventArgs e) { DataSourceBase dataSourceBase = (DataSourceBase)sender; dataSourceBase.ResultChanged -= HierarchyChanged;
dataSourceBase.HierarchyExpansionMode = HierarchyExpansionMode.DrillDown; dataSourceBase.UpdateVisualMembers(Infragistics.Olap.ExecutionContext.Rows); dataSourceBase.UpdateVisualMembers(Infragistics.Olap.ExecutionContext.Columns); dataSourceBase.HierarchyExpansionMode = HierarchyExpansionMode.SingleLevelOnly;
dataSourceBase.RefreshGrid(); } }
I suppose the issue here is produced by XamTree control we use in v11.2 to display the UI representation of the hierarchy in the pivot grid. I suggest you to complete expand/select/unselect actions before add the filter view model to Filters collection, because at this point the UI for the filter view model is not created yet.
Plamen.
>> I suggest you to complete expand/select/unselect actions before add the filter view model to Filters collection, because at this point the UI for the filter view model is not created yet.
Plamen, I'm sorry but I do not understand anything of what you said.
Remember that the Refresh method is called whenever the criteria filter for the grid is changed.
Do you have a code sample?
Once you have filter view model added to any of Rows/Columns/Filters collection like:
there will be created an UI element for it, the one you can see as drop down with the members hierarchy within.
So my suggestion was to do something like:
// create the view model
IFilterViewModel filterViewModel = ExposureGrid.DataSource.CreateFilterViewModel(
ExposureGrid.DataSource.Cube.Dimensions["PM_Name"].Hierarchies.First());
// set the filters state
FilterHelper.FilterOption(filterViewModel, "DeliveryDate", "All", false);
FilterHelper.FilterOption(filterViewModel, "DeliveryDate", "N/A", true);
// process the expansion state
foreach (Infragistics.Olap.Data.IFilterMember member in filterViewModel.FilterMembers)
FilterHelper.ExpandHierarchy(member, true);
// then add the filter view model to the target collection (UI elements are created)
ExposureGrid.DataSource.Filters.Add(filterViewModel);
In this way the UI elements (the XamTree items) are not involved to update their selection and expansion states every time a filter member is modified.
FilterOption method should be modified as well:
public void FilterOption(IFilterViewModel fvm, string tag, string value, bool set = true)
{
if (fvm.FilterMembers != null)
foreach (var filter in fvm.FilterMembers)
SetFilter(filter, value, set);
}
fvm.CommitChanges();