This is a migrated thread and some comments may be shown as answers.

ICollectionView Synchronization with DataForm

10 Answers 312 Views
GridView
This is a migrated thread and some comments may be shown as answers.
Jeff
Top achievements
Rank 1
Jeff asked on 26 Jan 2012, 05:46 PM
I'm trying to build a page using the DataForm ICollectionVew Synchronization demo as an example - having a GridView and a DataForm bound to the same CollectionView.

My underlying data is an ObservableCollection of my own record objects, which are instances of a class that implements INotifyPropertyChanged and IEditableObject. This collection is populated from a database.

In my VIewModel, I construct a QueryableCollectionView from the ObservableCollection, and I bind both the GridView and the DataForm to this.  Everything seems to work fine, as I navigate through the records, both on the form and in the grid.  Changing the selected record in the form changes the selected record in the grid, and vice versa.

If I edit a record in the form, the changes appear immediately in the grid, and if I hit cancel in the form, they immediately revert to what they were, in the grid.  (Which indicates that the ICollectionView.EditCancel is working right).

I have a CollectionChanged handler listening for changes in the QueryableCollectionView.  When I click on Delete, it sees a NotifyCollectionChangedAction.Remove, and deletes the record from the database.  And this seems to be working fine.

When I click "Add", I see a new row in the GridView, blank fields in the DataForm, and the CollectionChanged handler sees a NotifyCollectionChangedAction.Add, and is passed an empty instance of the record.  All it does then is populate the fields in the record that aren't visible in the GridView or the DataForm.  Later, when the user hit's the "OK" button on the DataForm, the ICollectionView.EditEnd method on the record is called - which does an insert or an update to put the record into the database.

And here's where things go wrong.  The new row in the GridView stays highlighted, like the grid thinks it's still being edited.  And while if I navigate to next and previous records in the DataForm, I see the selected row in the grid changing, if I change the selected row in the grid, I do not see the DataForm updated with the newly-selected record.

Something is not quite right, and I'm at a loss as to where to look.

Any ideas?

10 Answers, 1 is accepted

Sort by
0
Jeff
Top achievements
Rank 1
answered on 27 Jan 2012, 05:32 PM
I've built a simple project out of your demo code, and I'm not seeing the problem, there.  I've debugged into your assemblies with .NET Reflector in both cases, and haven't been able to identify where the difference is.

Currently, I'm alternating between extending your demo code, to make it more like my project, and simplifying my project to make it more like your demo, hoping that at some point I'll either get your demo to show the problem, or get my project to work.
0
Ivan Ivanov
Telerik team
answered on 31 Jan 2012, 01:02 PM
Hi Jeff,

I have prepared an example project for you, testing it with our latest official version - 2011.3.1220, but without any success in reproducing the reported issue. I am attaching it for your reference. Would you please share with us whether there are any major differences between my approach an yours? If you manage to change my project, so that the issue is reproducable, please send us the updated version, in order to debug it on our side. 

Kind regards,
Ivan Ivanov
the Telerik team
Explore the entire Telerik portfolio by downloading the Ultimate Collection trial package. Get it now >>
0
Jeff
Top achievements
Rank 1
answered on 31 Jan 2012, 04:42 PM
I was not able to replicate the problem in the sample you sent, which doesn't surprise me.  I wasn't able to replicate it in your demo, either.

I was able to make the problem go away, in the program where I did have the problem, by doing something that shouldn't have made any difference at all.

I'm trying to build a WPF app on top of an established set of base libraries, that includes a home-brewed ORM that we've been using and extending for a good many years.  What I've been doing, the last few weeks, is extending that ORM so that the objects within it can be used in WPF without a lot of interfacing code.

I'd made a couple of changes, so far:

  1. I'd added a select-into method to our query objects, so that we could run a query and then clear and populate an existing collection, instead of always returning a new collection.  If the collection in question is an ObservableCollection that is bound to a WPF control, we can then re-run the query without having to rebind the collection.
  2. I've added INotifyPropertyChanged, IEditableObject, and IEquatable, to our record objects.

Then I'd run a query, populate an ObservableCollection with the records returned, wrap a QueryableCollectionView around the collection, and then see the behavior I described.

If, instead, I created an ObservableCollection of a ViewModel class, and copies the data from the records into ViewModel objects, I'd not see the problem.  The VIewModel, of course, implementing INotifyPropertyChanged and IEditableObject.

The one thing that jumps out at me is that the ORM record class implements IEquatable, and the ViewModel class doesn't. I'd not noticed that until I started trying to explain this to you.  It may have nothing to do with the problem, or it may. I will explore the possibility, the next time I have a chance to spend some time on the issue.  But that's going to be a couple of days, at best.

0
Jeff
Top achievements
Rank 1
answered on 31 Jan 2012, 08:55 PM
I have been able to replicate the problem, in a simple demo app.

It seems to show up when the Items are of a class that implements IEquatable<>.

In the attached app, click on the "Add" button in the form.  Enter a first name, and click on "OK".

Then select a different row in the grid.  The newly-added row stays highlighted in the grid, and the form doesn't change - it continues to display the added record.

Comment out IEquatable, on the Person class, and everything works as expected.

I won't, at this point, offer an opinion on whether this is a problem in your controls not supporting IEquatable properly, or of my having done something wrong in my implementation of IEquatable.

I'd attach a zip, containing the solution, but your forum software won't let me, so I did so in support ticket 507092.
0
Maya
Telerik team
answered on 02 Feb 2012, 12:11 PM
Hello Jeff,

Actually, it is not recommended to change the hash codes of the items as RadGridView selection mechanism relies on it and the fact that it is unique. Once you interfere into this mechanism, you will get quite undesirable and unexpected behavior - just as the one you encountered. 
What I would suggest is to remove the implementation of GetHashCode() method. Still, you can keep the Equals() methods and work with them.
 

Regards,
Maya
the Telerik team

Explore the entire Telerik portfolio by downloading the Ultimate Collection trial package. Get it now >>

0
Jeff
Top achievements
Rank 1
answered on 02 Feb 2012, 04:18 PM
Changing Equals() but not changing GetHashCode() would result in objects that had the same hashcode comparing as not equal - which would likely break more than just your grids.

Still, now that I know this is the cause of the problems I've been seeing, it's easy enough to populate the collections the grid is binding to with objects that don't change either.
0
Arinc
Top achievements
Rank 1
answered on 30 Nov 2012, 09:57 AM
I downloaded and took a look at the example project, thank you first of all.
---

I added a new line to View as:
<telerik:RadDataForm Grid.Row="2" ItemsSource="{Binding Players}"/>

I want to do extra operations like adding, editing, deleting etc. for "Players" list, there is an available dataform on View after adding the XAML code, but although I select an item, it is not selected or there is no change on the dataform fields, and also when I add new item for "Players" dataform, it's not related to any Clubs list (it's not listed in anywhere).

Can you explain how to do this. I hope I could tell the problem...

Thanks.

---

I think I've found the solution and huh it is really simple :)

<telerik:RadDataForm Grid.Row="2" ItemsSource="{Binding Players}" DataContext="{Binding Clubs}"/>
0
Maya
Telerik team
answered on 03 Dec 2012, 08:10 AM
Hi Arinc,

You can also try setting DataContext of RadDataForm to SelectedItem of the grid and specify it through ElementName binding. Another possible approach would be to bind the ItemsSource as follows:
ItemsSource="{Binding SelectedItem.Players, ElementName=clubsGrid}".
 

Greetings,
Maya
the Telerik team

Explore the entire Telerik portfolio by downloading Telerik DevCraft Ultimate.

0
Arinc
Top achievements
Rank 1
answered on 03 Dec 2012, 08:44 AM
Hi Maya,

Although I said "ok, I solved the problem", I couldn't.

(I'm sending a screenshot, please look at it)

The problem is that; my parent list is "Clubs", and child list is "Players". When I click "1" or "2", Clubs's current item is changed and so "Yeni Proje Ekle" dataform's item is changed. At this point, because of selection of first item as current item, "Players" dataform's item is binded as "3" element. And although I click "4", there is no change in "Yeni Proje Ekle" dataform.

I guess it happens because of datatemplate. Binding Observable Collection items and using them in datatemplate logic is not valid, I can't access the selected / current datatemplate item from XAML.

I hope we can find a solution for this problem :)

Thanks...
0
Maya
Telerik team
answered on 03 Dec 2012, 09:46 AM
Hi Arinc,

The cause of the problem is that the SelectedItem of clubsGrid is not changed when you select an item from its child grids. What I could suggest is to expose a property in your ViewModel - MySelectedItem for example and bind it to the SelectedItem of the parent and child grids and DataForm. For example:

<telerik:RadGridView x:Name="clubsGrid" SelectedItem="{Binding MySelectedItem}">
 
    <telerik:RadGridView SelectedItem="{Binding MySelectedItem, Source={StaticResource MyViewModel}}" />
 
 
</telerik:RadGridView>
 
<telerik:RadDataForm ItemsSource = "{Binding MySelectedItem.Players}"  />

In this case the DataContext of the main grid and the data form is your ViewModel.
However, following this scenario will mean that you have only one SelectedItem (for the main grid and all child-grids). 

Kind regards,
Maya
the Telerik team

Explore the entire Telerik portfolio by downloading Telerik DevCraft Ultimate.

Tags
GridView
Asked by
Jeff
Top achievements
Rank 1
Answers by
Jeff
Top achievements
Rank 1
Ivan Ivanov
Telerik team
Maya
Telerik team
Arinc
Top achievements
Rank 1
Share this question
or