EF 4.1 local: when is it instantiaced? - wpf

I have a class, DataBaseManager, that use EF 4.1 to access to data base. This class hava a method search that search information in the data base. The resume version is that:
public ObservableCollecion<Authors> searchAuthtors()
{
_Context.Authors.SqlQuery("select * from authors").ToList<Authors>();
ColectionAuthors = _Context.Authors.Local;
return ColectionAuthros;
}
Also, this class has a property, _colAuthors, public, that I use to link external classes with this data manager. The idea it's, in WPF, use this _colAuthors to binding a dataGrid.
Well, in my ViewModel, in which I have a property Authors, which I use to binding the dataGrid of the View, in the constructor I do this:
public myViewModel()
{
_dataManager = new DataBaseManager();
Authors = _dataManager.ColectionAuthors;
}
I have the view, with a dataGrid, a button to update the changes and a button to search authors.
If first I search Authors, if in the dataGrid I delete, add or modifed items and later I click the button to update changes, it's works fine, add, delete or update the information and if I search again, I can see the correct information.
However, if I don't do a first search, I only add a register, because I don't have in the dataGrid registers to modify or delete. Well, if I add register and I click the update button, the changes has not been saved in the data base.
I think that this is because the context.Authors.Local is not been "create" until I make a first search, so when I do Authors = _dataManager.ColectionAuthors; I can't add the element to local, so when I do the savechanges() there is no elements in local to save in the data base.
I am right? is there any way to add elements to the context before doing the first search?
Thanks.
Daimroc.

Related

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("")

How to edit properties of a ViewModel object but only apply changes when clicking a button in the View

My screen has a list of objects of type Person, and a form that displays the person properties (name, address, weight, etc.) via databinding.
I want to be able to:
Click in a button "Edit properties", and start modifying the person's properties (I can already do that using Commands in the ViewModel);
If I click "Cancel", the edited info "rollback" to the original unmodified values of that person;
If I click "Save changes", JUST THEN the person's name changes in the person list.
My problem right now is that, as I am editing the forms, the original properties are updated, so to say, in realtime, and if I decide to cancel, I have not the original values to "go back".
I considered to Clone the selected person, but that seemed to be odd. I think a better approach would be to change only the text properties of the field, and update back only when clicking to submit changes, but I don't know how to do it, specially how to preserve databinding consistency.
When you bind, use UpdateSourceTrigger=Explicit. That will tell XAML not to update the source binding until you tell it to. Then, when your Save button is clicked, you can call UpdateSource on the binding to push the contents of your controls back to the Person object, something like:
var nameBinding = nameTextBox.GetBindingExpression( TextBox.TextProperty );
nameBinding.UpdateSource();
To cancel, use UpdateTarget instead, which will push the data in the Person object back to your control.
You can try it with this Undo/Redo approch
http://blog.notifychanged.com/2009/01/30/using-the-viewmodel-pattern-to-provide-undo-redo-in-wpf/
Or
You could have a a Current and Previous property created in View model to which is going to hold the edited values and the other will have original value. The required action of rollback can be performed be reassigning the values
There are also open-source projects available to help with this, including http://undo.codeplex.com/

ADF LOV Not Refreshing

I have an interesting situation. Working on an 11.1.1.3 ADF Application.
I have an editable table, which uses an LOV. The respective LOV has a maintenance page, where we populate a database table with data that the LOV uses.
If i'm inserting new records into the LOV Database Table, the corresponding LOV does not get those changes. However, if there is an UPDATE of existing records, it seems to work ok.
It appears the iterator is not updating. Because if i start up a new application session in a new browser window, i'll see the new changes.
The LOV doesn't have it's own iterator in the Page Bindings (Its using a View Accessor in my view object), so i'm not sure how to tell the iterator to refresh or executeQuery()...
Thank you!
Right now, my only solution is this. I don't like it, but it works...
Exposed View Row Impl class, and included accessors on my Editable ADF Table's View Object. This way i have programmatic access to my accessors that run the LOV.
Then i located my view accessor, getter method. And told it to re-execute the query. Worked like a charm:
public RowSet getAllSmsModules() {
RowSet rs = (RowSet)getAttributeInternal(SMSMODULESALL);
rs.executeQuery();
return rs;
//return (RowSet)getAttributeInternal(ALLSMSMODULES);
}

Combobox clearing value issue

I've stumbled on an issue with Comboboxes in javafx2.2. This is the scenario:
Users click on the 'editFile' button.
Another pane becomes visible (with the setVisible method).
This pane contains 6 comboboxes.
Three of them have fixed items: cboReport, cboSales, cboSend. Three of them get their data from a db (ObservableList) and get populated when the pane becomes visible: cboFile, cboCustomer, cboVet
The user selects a file number from the cboFile. The rest of the comboboxes are beeing set with the correct values.
The user presses the save button, the file gets saved as intended.
Next the user presses a close button.
When the window closes, the data on the pane gets resetted through a resetGUI_editFilePane() method. There is have lines like:
...
cboReport.getSelectionModel().clearSelection();
cboSales.getSelectionModel().clearSelection();
cboSend.getSelectionModel().clearSelection();
cboFile.getSelectionModel().clearSelection();
cboCustomer.getSelectionModel().clearSelection();
cboVet.getSelectionModel().clearSelection();
cboFile.getItems().clear();
cboCustomer.getItems().clear();
cboVet.getItems.clear();
...
When the user opens the pane again by pressing the 'editFile' button I notice that only the 'fixed item' comboboxes have cleared their selection, the dynamicly filled comboboxes show the last selected item although the value from the selection itself is null. This looks like a graphics bug to me or am I doing something wrong?
Is there any way around this issue or what is the best method to reset a combobox?
EDIT 2014/08/27:
This is officially not a bug(clearSelection() does not clear value):
https://bugs.openjdk.java.net/browse/JDK-8097244
The official "workaround" is to clear the value of the ComboBox after clearing selection.
cb.getSelectionModel().clearSelection();
// Clear value of ComboBox because clearSelection() does not do it
cb.setValue(null);
It is very simple. You just need to work with the value property of ComboBox. here you go ....
ComboBox c;
c.valueProperty().set(null);
I hope this works for you :-D
I ran into nearly the exact same situation and came across your question while looking for a solution. Fortunately, I came up with a workaround that forces the ComboBoxes to reset. When you reset the data on your pane, instead of doing something like:
cboVet.getSelectionModel().clearSelection();
cboVet.getItems.clear();
do something like this...
parentNode.getChildren().remove(cboVet);
cboVet = new ComboBox(); // do whatever else you need to format your ComboBox
parentNode.add(cboVet);
You'll also need to do a setItems() again on your ComboBox so the new one will be populated. This is not an ideal solution but it seems to be working as I expect the provided clearSelection() method would.
You can retrieve the items and have them all removed:
cboVet.getItems().removeAll(cboVet.getItems());
I've just tested a working solution with the Java JDK 1.7.11:
combobox.setSelectedItem(null);
combobox.setValue(null);
Hope it helps :)
I use reflection with direct manipulation of buttonCell field in ComboBox skin:
#SuppressWarnings({ "rawtypes", "unchecked" })
public static <T> void resetComboBox(ComboBox<T> combo) {
Skin<?> skin = combo.getSkin();
if(skin==null){
return;
}
combo.setValue(null);
Field buttonCellField;
try {
buttonCellField = skin.getClass().getDeclaredField("buttonCell");
buttonCellField.setAccessible(true);
ListCell buttonCell = (ListCell) buttonCellField.get(skin);
if(buttonCell!=null){
StringProperty text = buttonCell.textProperty();
text.set("");
buttonCell.setItem(null);
}
} catch (NoSuchFieldException
| SecurityException
| IllegalArgumentException
| IllegalAccessException e) {
e.printStackTrace();
}
}
I think it's also possible by providing your own buttonCell implementation through buttonCellFactory property
I had the same problem with a ComboBox. The buttonCell of the ComboBox is not updated correctly when I change the items of the ComboBox. This looks like a graphics bug.
I use direct manipulation of buttonCell field in ComboBox.
combo.getButtonCell().setText("");
combo.getButtonCell().setItem(null);
This is the best solution I've found without recreate the ComboBox.
To clear SelectionModel I found nothing better than creating a new instance of Combobox (previous answers update):
myParentNode.getChildren().remove(myCombobox);
myCombobox = new ComboBox();
myParentNode.add(myCombobox);
But this solution evolves other problems: if you use fxml, this combobox will be placed in the wrong place and with wrong parameters. Some fxml parameters are hardly reproduced directly from your controller class code and this is awful to do it every time you need to clear the combobox.
The solution is using custom components instead of creating instances directly in main controller class code, even if these components are standard. This also helps to free some lines in your main controller class by moving component related event methods and other methods to a separate class file, where you use a reference to your main controller class.
How to create custom components in JavaFX FXML Application can be found in http://docs.oracle.com/javafx/2/fxml_get_started/custom_control.htm , but note that CustomControlExample class is not needed for every custom component in your application, if it already has an entry point class with start(Satge stage) method.
How to resolve possible errors with reference from custom component controller class to main controller class can be found in JavaFx: how to reference main Controller class instance from CustomComponentController class?
I need to clear selection of the combo box. And this code worked for me:
List<Object> list = new ArrayList<>(comboBox.getItems());
comboBox.getItems().removeAll(list);
comboBox.getItems().addAll(list);

How do I navigate a table using the entity framework?

I'm trying to create a simple table navigation screen in WPF using the entity framework on a database with one table, Students. The screen basically has the the students name and surname and back and forwards button.
The datacontext is pointing directly to the Students table and is setup as follows:
private DBEntities _entity = new DBEntities();
this.Datacontext = _entity.Students;
This works and I see the first entry on the table on the screen.
My problem is I can't see any way to navigate to the next entry when I click the next button.
There is First() method on Students but no Next().
All the solutions I've found via google dump the entire table in a List and navigate the list.
I'm wondering if there isn't a simpler way that I'm missing?
msdn topic here...
First get the collection as an ICollectionView,
ICollectionView view1 = CollectionViewSource.GetDefaultView(_entity.Students);
Now you can navigate the collection, in this case you can use MoveCurrentToNext

Resources