0
votes

I have an interesting problem with the Silverlight DataForm and child collections. I've also got a solution that works but it feels like a hack (it is a hack) and I was wondering if anyone had a more elegant solution.

I've got a DataForm bound to a collection of GroupViewModels. Each GroupViewModel has a ObservableCollection of UserViewModels which I'd like the user to be able to add to and delete from when the EditTemplate of the DataForm is shown.

The UI for doing that is a simple ComboBox with a list of all Users and a ListBox of the users currently in the group. There is an add and a delete button to move a User from one list to the other.

Now,...the view model that the DataForm is bound to implements IEditableObject,..which is cool because I get rollback behaviour if an edit is cancelled but in this case it's not quite enough. I need a way of telling the DataForm whether my VM is in a dirty state or not explicitly.

Since my ViewModel has a SelectedUserToAdd property which the SelectedItem of the all users ComboBox is bound to, when the user selects a user to add, the PropertyChanged event fires on my VM and the DataForm thinks that something has changed and the commit (OK) button lights up. It also lights up when the selection is changed in the ListBox because of the SelectedUserToRemove property.

Obviously what I want is for the commit button to light up if the UserViewModels in the ListBox have changed.

The solution is straight forward. I can stop the commit button lighting up if I remove change notification from the SelectedUserToAdd and SelectedUserToRemove properties and I can get the commit button to light back up by using a dummy property called 'Dirty' which raises NotifyPropertyChanged when either the AddUser or DeleteUser command gets fired.

As I say,..it works but it feels wrong. Anyone got a better idea?

Much thanks in advance.

1

1 Answers

1
votes

From my experience I know the DataForm isn't idealistic to use and has some limitations. This being said, I think your solution is cleaner then the one I'm proposing but I'm just giving you an alternative.

I can tell you of a way to make the dataform 'ignore' (not really) certain property notifications. What you could do is check whether a certain property is raised and if that property should be ignored you manually ignore reset the commit button to its previous state:

        someViewModel.PropertyChanged += (sender, e) =>
                                             {
                                                 Grid dependencyObject = VisualTreeHelper.GetChild(TheDataForm, 0) as Grid;
                                                 var commitButton = dependencyObject.FindName("CommitButton") as Button;
                                                 commitButton.IsEnabled = !e.PropertyName.Equals("PropertyToIgnore");
                                             };

You can then tweak it by inheriting from the dataform and creating a dependencyproperty in which you can bind the properties to ignore.

Again as I said, I think your solution is the cleaner one.