Hello!
I need a way to initialize FlatDataSource from code. I use MVVM pattern and currently FlatDataSource in my ViewModel is populated with initial items and initialized only after view have been initialized. Now if I want to do something with initialized datasource, I do this in ResultChanged event handler. But this breaks View-ViewModel separation and I can't properly test my code.
Maybe I'm missing something? How can I initialize FlatDataSource with items from ItemsSource without loading the PivotGrid?
Here is my code to generate FlatDataSource:
DataSource = new FlatDataSource { ItemsSource = Items, Cube = DataSourceBase.GenerateInitialCube("DistributorInventory"), Rows = DataSourceBase.GenerateInitialItems("[Distributor].[Distributor]"), Columns = DataSourceBase.GenerateInitialItems("[Date].[Date]"), Measures = DataSourceBase.GenerateInitialItems("Value") };
var cubeMetadata = new CubeMetadata { DisplayName = "Cube", DataTypeFullName = typeof(DistributorInventory).FullName }; cubeMetadata.DimensionSettings.Add(new DimensionMetadata { SourcePropertyName = "Value", DisplayName = "Value", });DataSource.CubesSettings.Add(cubeMetadata);
var datesHierarchy = new HierarchyDescriptor(p => p.Date) {HierarchyDisplayName = "Date"}; datesHierarchy.AddLevel(p => p.MonthText, "Month"); datesHierarchy.AddLevel(p => p.WeekText, "Week"); DataSource.AddHierarchyDescriptor(datesHierarchy);
var itemsHierarchy = new HierarchyDescriptor(p => p.Distributor) {HierarchyDisplayName = "Distributor"}; itemsHierarchy.AddLevel(p => p.Distributor, "Distributor"); itemsHierarchy.AddLevel(p => p.Address, "Address"); itemsHierarchy.AddLevel(p => p.Item, "Item");DataSource.AddHierarchyDescriptor(itemsHierarchy);
DataSource.ResultChanged += OnDataSourceOnResultChanged;
Hello and thank you for posting!
I have been looking into your description and I am not completely sure what you are trying to achieve. The rows and cells are actually created when the control where they are displayed is loaded. Would you like to be able to modify them before loading the data in XamPivotGrid? Could you give me more details of the goal you are trying to achieve so I could try to provide you a better solution?
Hello Maria!
Yes, I need to have rows and cells created without XamPivotGrid control (in code-behind). I need this because we implement MVVM pattern (which is quite common for WPF), and one of it's main paradigms is that ViewModel should never know of View. And concerning that FlatDataSource is implementing IOlapViewModel interface I found very strange that FlatDataSource might depend on View (which is XamPivotGrid control).
In case if it's not possible (althought I very much hope that it is), how can I use XamPivotGrid (which is in View) with data from my ViewModel? FlatDataSource's ItemsSource property is not DependencyProperty, so I can't bind it to my items collection in my ViewModel.
Hello,
In order to initialize the data source in code behind you have to call IOlapViewModel.LoadSchemaAsync method. This call will initialize the data source's metadata tree - the cube and its dimensions, hierarchies, levels and measures. Once the metadata is loaded IOlapViewModel.Initialized event is fired and then the initial Rows, Columns, Filters and Measures are set.
Regards,Plamen
Thank you for your answer!
This works, but now I have two OnResultChanged calls: I think that one is from LoadSchemeAsync, and other is from XamPivotGrid. I solved this by checking DataSource.Result.ColumnAxis.Tuples[0].Members[0].UniqueName == String.Empty.
Thank you for your feedback. I am glad that you resolved your issue and I believe that other community members may benefit from this as well.
Thanks again.
Hello again!
I'm sorry, but it still isn't working. I tested initializing the DataSource without PivotGrid control by removing control from the view, but now I'm creating unit tests with the data and it's not working.
ResultChanged event is not firing now! I've tried setting a breakpoint to DataSourceBase.RunWorkerCompleted (the method from where OnResultChanged is called when everything works fine), but the breakpoint is never in my unit test!
That's the code:
DataSource.ResultChanged += OnDataSourceOnResultChanged; DataSource.LoadSchemaAsync();
private void OnDataSourceOnResultChanged(object sender, ResultChangedEventArgs args) {
// never gets here
if (DataSource.Result == null || DataSource.Result.ColumnAxis == null || DataSource.Result.ColumnAxis.Tuples.Count == 0 || DataSource.Result.ColumnAxis.Tuples[0].Members.Count == 0 || DataSource.Result.ColumnAxis.Tuples[0].Members[0].UniqueName == String.Empty) return;
// ... Here goes conditions checking, but it never gets here...
DataSource.ResultChanged -= OnDataSourceOnResultChanged; }
I looked at your code again and I think you might need to add the metadata settings first and then set the items source.
I have logged this with development under ID: 169353 and I have also created a support ticket on your behalf: CAS-134647-L9H5F6 and have linked the development issue to it, so that you can get automatically updated, when a Service Release containing the fix is available for download. You can get the new version from our website’s “My IG”, “My Keys & Downloads” tags: https://es.infragistics.com/Membership/Default.aspx?panel=Downloads#Downloads
You can also monitor the support ticket’s progress through the “My Support Activity” tag: https://es.infragistics.com/Membership/MySupport.aspx
Hello?
I just want to know that if my question is being reviewed or not.
I'm just checking if my attached example was helpful or if you need additional info from me.
Thanks!
Yes, I have tried this too but no luck :(
Look, I have a repro example for you, I think this will help you to understand my problem and help me solve it.
What I mean is to make sure you have removed/commented out this line of code:
DataSource = new FlatDataSource {
// do not set the items source yet// ItemsSource = Items,
and put it at the very end of your initialization code:
DataSource.ItemsSource = Items;