NullReferenceException thrown in NotifyPropertyChanged when switching views with edit in progress - silverlight

I have a series of views that are to be displayed depending on the currently selected item in a tree within a parent view. These views are created and registered with the region during the initialization method of the parent view and are being correctly deactivated/activated, therefore giving the effect of swapping in/out the correct view. These views have a single underlying viewmodel as their datacontext, which contains data objects supporting INotifyPropertyChanged.
This solution works if there are no currently outstanding edits in progress within the child view but if there is a edit in progress in a view (i.e. the user has changed the contents of a description but hasn't clicked out of the text box) and that view is deactivated (i.e. the a different tree item is clicked within the parent view, thus causing a de-activation to occur) a NullReferenceException is being thrown in the NotifyPropertyChanged() of the underlying data object attached to the now deactivated view.
What seems to be happening is this:
An edit is started by the user in the child view
The user clicks an item in the tree in the parent view
The controller picks up the change in the selected item in the tree
The current child view is deactivated
The new view is activated
The change from the edit happens to the underlying data object (the set method is getting called)
A change notification event is generated by the data object as a result of this change
A null reference exception is thrown.
Presumably, this change notification event is being sent to the now de-activated view, but the view is not null.

I have not tried this myself, but I believe one solution was to listen for the deactivate event of the view using IActiveAware and cancel any editing.
See if this link helps.

Related

Updating Main Window from page in a frame

I'm currently developing a WPF application using the MVVM framework. And I have this functionality:
I have a main window which has a combo box and frame (where I put my pages) and a view model. One of the pages in that frame is where a user can add a data and these data are used to populate the combo box in the main window. My problem is how to automatically update the items in the combo box after adding a data from that page. Btw, this page has a different view model too.
Thanks.
You can establish an event in the page viewmodel for changed data. Then subscribe to those events within the window viewmodel and update the combobox items accordingly.
You have access to the parent window from iframe via window.top. You have to write this code in your page what you have loaded in iFrame.
window.top.document.getElementById("combobox_element_id").value='Your New Value';
best of luck
You can pass the Source DataContext of ComboBox (ObservableCollection) to page ViewModel so you can simply modify the collection from Page view model.

How to reset a viewmodel in mvvm

How can I reset my viewmodel when the user clicks new button on the view that has the viewmodel as it's datacontext?
For example:
If I have a view NewCustomer and upon save, the data is saved to the DB and the newly created account number is displayed. But when the user clicks the New button in the screen, I want the view (viewmodel) to be reinitialized. Or if the user clicked cancel in the screen to clear all changes.
How can I achieve this? I am using Prism 5.0 and Unity as my container.
If I used IRegionMemberLifetime, I can clear the viewmodel data when I navigate away and navigate again to the view (by setting the KeepAlive as false on clicking New button before navigating away). But I want the form to be cleared without navigating. Can this be done?
You could have a screen/workspaceViewModel, and another ViewModel wrapping your data.
So two classes: CarScreenViewModel and CarViewModel.
The CarScreenViewModel would have a property, say CurrentCar, which reflects what is currently selected in the screen. Then, when clicking the Create button, you simply set:
CurrentCar = new CarViewModel();
Resetting partially loaded data will only lead to behaviour that is hard to reproduce. It is better to start with a fresh instance.
Your standard approach will be something like below
ViewModels
CustomersContainerViewModel which contains
a collection of CustomerViewModel s
and ICommands like
CreateNewCustomer
DeleteExistingCustomer
UpdateExistingCustomer
Your View will contain
the CustomersContainerView which will contain
a collection of Customer Objects in your required UI element
a button to Create new customer (which will launch a new screen which contains the newCustomer fields it can also contain cancel, which will just close the form)
a button to delete (can also be a ContextMenu)
a button to update (can also be a ContextMenu) which will launch a customer form filled with details from DB.
Hopefully this makes some sense... Let me know if you have problem with any of the above
Update - Forgot to add. NewCustomer Command will add a new Customer object to your CustomerCollection and that should open a NewCustomer form (or whatever you chose) for user to input the customer details. Cancel/Delete will just remove that record from the collection. Delete will update the DB as well in addition
In my case
yourViewName.variableName.postValue("")

WPF : update parent form after canceling edit in child form (reset DataContext)

I have a parent form with a customers listing in a WPF datagrid.
Editing a line of the form is done in a child form: click on a button in a line, open child form using selected item of datagrid and assign it to child form datacontext.
When a PropertyChanged event is triggered in the child form, the line being edited in the parent form listing updates.
If I decide to cancel my current modification by clicking on a cancel button in child form, I restore the original values ​​of the edited customer: before editing I made a clone of to be edited customer. Then now I reset child form DataContext by setting it to null then to the cloned customer. This was the hack I read on SO about forcing DataContext to refresh with DataContext itself being changed, not properties on its objects.
After canceling edit, child form shows the values I expect (properties of cloned customer), while the associated line in parent form listing didn't update: still shows edited customer values.
How can I ask parent form to update itself? I'm afraid I lost some references between objects by reassigning child form datacontext to a new object (loosing link to parent form datagrid interesting line selected item).
Thanks for your guidance,
EDIT :
When I am ready to edit a customer in child form, I assign datagrid selected item to a static variable of my application since it's mono-user, so that it's easier to handle "current customer". When I cancel edition, this static variable value has changed, but maybe I have to assign it to parent form datagrid selected item back too?
I was right: after child form closes, I must update parent form datagrid collection, at right index, with updated object.
// update static variable
SocodifApp.Client = ((Client) Listing.SelectedItem);
ClientForm editClientForm = new ClientForm();
editClientForm.ShowDialog();
// Get modified static variable after child form closes and update datagrid collection
// relevant item
_dataContainer.Clients[Listing.SelectedIndex] = SocodifApp.Client;

wpf datagrid : remove dependency between main listing / child edit form?

I have the following : a datagrid which DataContext is an object with a list of Customer objects. I pull the values from database.
To edit some customer, I click on a button in a row and open a new form with customer details. For now I pass the relevant customer object (thus reference) to child form DataContext.
I'm not fine with this because any modification in customer form are show in customers listing form.
I'd like both to be independent, and get customers listing form data refreshed only when I click on "save" button in child form (nothing done when I click on "cancel") that will trigger database reading for edited customer updated values.
Tell what you think would be right apart from these ideas :
Make a clone of Customer object and pass this clone to child form. I'm not fan of this.
Reread customer to edit from database to have a complete new object with relevant data. Seems not fun to ask to database again since my customer data is already completely read, in this case.
Thank you for suggestions.
I went on with my own way of doing this without working with delegates : WPF : update parent form after canceling edit in child form (reset DataContext)
A bit cumbersome but works.
I also used this nice way of cloning: WPF : update parent form after canceling edit in child form (reset DataContext)
But I did some changes: I added "where T : class" to the generic method signature.
I also simplified the code for testing for a null parameter :
// Don't serialize a null object, simply return the default for that object
if (source_ == null)
{
return default(T);
}

WPF composite Application - tab region - view not getting focus

I'm just starting to use the composite application libraries for WPF. In my shell I have a region in a tabcontrol that is used to display different types of views. I also have a toolbar with buttons hooked up to commands, for example save. The commands are bound in my views, and the views have the canExecute and execute methods.
The idea is that when i click a tab, my tool bar buttons should be enabled or disabled according to the methods in the view. Problem is when I switch tabs the view is not getting the focus and the canExecute for that view doesn't get called. The toolbar buttons remain connected to the commands in the previously selected view, and reminds that way until i actually click on the new view
I'm stumped right now on how to force the view to get the focus. I've tried looking at the tab's content when the tabs SelectionChanged and setting the focus there but its not making a difference. Any ideas?
Try listening for the View.Loaded event, then call View.focus() in the handler. Wpf will not accept focus requests before an element is initialized and loaded. Since the SelectionChanged event is raised before the view is loaded, the focus request will just be ignored. The loaded event is called each time the element is shown after being hidden.
See this blog post for more information on focus:
http://www.julmar.com/blog/mark/PermaLink,guid,6e4769e5-a0b3-47b2-a142-6dfefd0c028e.aspx

Resources