Hi,
I have some problem to refresh value on column who depend of child item.
My model is define in the sample.
I would like to have the Sum of Qty delivery for each items
I tried something like this :
<ig:XamGrid x:Name="ControleGrid"
Width="auto"
ItemsSource="{Binding Items}"
AutoGenerateColumns="False"
IsAlternateRowsEnabled="False">
<ig:XamGrid.Columns>
<ig:TextColumn Key="DeliveryQuantityQty" ></ig:TextColumn>
<ig:ColumnLayout Key="Deliveries">
<ig:ColumnLayout.AddNewRowSettings>
<ig:AddNewRowSettingsOverride AllowAddNewRow="Bottom"/>
</ig:ColumnLayout.AddNewRowSettings>
<ig:ColumnLayout.Columns>
<ig:TextColumn Key="Qty" ></ig:TextColumn>
</ig:ColumnLayout.Columns>
</ig:ColumnLayout>
</ig:XamGrid.Columns>
</ig:XamGrid>
Problem : When i add row in the Delivries in the ColumnLayout the parent column DeliveryQuantityQty is not update.
When i use sort function of XamGrid on column the DeliveryQuantityQty is update.
I would like to get the new value after adding Delivery.
Is there any way to avoid this problem ? (use summary function in header of columnlayout is a possibility ?)
Thanks a lot for your help.
Hello,
Thank you for the sample application you have provided.
The reason the "Qty" column from the top layout is updated only when performing operations like sorting is because the XamGrid gets all property values when sorting and in this case the QtyDelivered property returns the latest calculation result.
In order to keep the QtyDelivered property updated when adding new child rows, I can suggest you a couple of approaches:
1. Handle the RowAdded event of the XamGrid by checking if a new row has been added to the child layout. If so, then update the QtyDelivered property of the parent row manually.
private void grid_RowAdded(object sender, RowEventArgs e){ var grid = sender as XamGrid; var addedRow = e.Row; if (addedRow.ColumnLayout == grid.ColumnLayouts["Deliveries"]) { var parentRow = addedRow.ParentRow; var parentRowItem = (parentRow.Data as Item); parentRowItem.QtyDelivered = parentRowItem.Deliveries.Sum(D => D.Qty); }}
if (addedRow.ColumnLayout == grid.ColumnLayouts["Deliveries"]) { var parentRow = addedRow.ParentRow; var parentRowItem = (parentRow.Data as Item); parentRowItem.QtyDelivered = parentRowItem.Deliveries.Sum(D => D.Qty); }}
2. Use an ObservableCollection instead of a List for storing the Delivery items. This way you can hook for the CollectionChanged event of the collection and update the QtyDelivered property with a private set within the Item class context.
this._Deliveries = new ObservableCollection<Delivery>();this._Deliveries.CollectionChanged += (sender, e) =>{ if (e.Action == NotifyCollectionChangedAction.Add) { QtyDelivered = this.Deliveries.Sum(D => D.Qty); }};
I would suggest going with the second approach, since it keeps the MVVM pattern and the ObservableCollection itself is more suitable when it comes to storing data for visual representation.I have modified your sample with the second approach from above.
If you have any questions on the matter, please let me know.
I have some question about second approach :
My items are retrieve by relationship from object generated by EDMX diagram :
public EntityCollection Livraisons //as deliveries { get { return ((IEntityWithRelationships)this).RelationshipManager.GetRelatedCollection("EasiiDB_001Model.LivraisonCommandeFournisseurLigne", "Livraison"); //from item } set { if ((value != null)) { ((IEntityWithRelationships)this).RelationshipManager.InitializeRelatedCollection("EasiiDB_001Model.LivraisonCommandeFournisseurLigne", "Livraison", value);//from item } } }
In my main code i have 3 level :
Order => Items => Deliveries
Did you think i have to generate multiple ViewModel classes ?
ObservableCollection and itemsViewModel composed with ObservableCollection ?
In my ViewModel I have
My XamGrid is bind to ObservableCollection Orders
1st ColumnLayout is binding on Items (relationship by model)
2nd ColumnLayout is bind on Deliveries (relationship by model)
I created an example more closer than my developpement.
Thanks a lot for your help
Hello,Using the ObservableCollection instead of a List will set changed notifications when items are added and removed from the collection. Having the three level data could be handled using nested ObservableCollections and there is no need for separate viewmodel classes.Please let me know if you have any other questions.
Hello Maria,
In my sample i already use an ObservableCollection<Order>.
Order.Items is return by EntityFramework.
It's the same for Item.Deliveries.
This is generated items by diagram.
Could you try to modify my sample because i don't really know how can i avoid this problem.
Thanks a lot.
Thank you for the modified sample you have provided in your previous reply.
Since the Deliveries collection you are using is of EntityCollection type and does not implement the INotifyCollectionChanged interface (this is the interface that the ObservableCollection implements and thus contains the CollectionChanged event), an approach I can suggest you is to create an additional wrapper collection class, that uses the EntityCollection and implements the INotifyCollectionChanged interface according to the entity collection.
This way you will be able to analogically hook for the CollectionChanged event of the wrapper class and make the necessary checks/changes over your data.A similar issue has been discussed at the following topic: http://stackoverflow.com/questions/628437/best-practices-for-using-the-entity-framework-with-wpf-databinding
If you have any further questions, please let me know.
I created sample with wrapper class.
Could you say me if i could do better than this way ?
I had to create 2 wrapper classes.
Thanks for your help.
Thank you for the new sample you have provided.
The functionality you were aiming for in regards to updating the parent row based on it's children rows' values seems to be achieved. The wrapper classes look well implemented.
Any further manipulation in the application would strongly depend on the whole implementation of the behavior you are aiming for.