I have a combobox that goes out to the database to load it's content on clicking the dropdown arrow. if after the dropdown box is shown with data and I don't select anything, than the current value of the combobox is blown away. Inside my routine to load data, I tried saving the current value and restoring it back after the loading is done. doesn't work.
[Edit] Added the code from the comment here for legibility
MyUltraCombo myultracombo = new MyUltraCombo();
//MyUltraCombo inherits from UltraCombo inside MyUltraCombo, I keep the table name to load from
MyUltraCombo.BeforeDropDown += new System.ComponentModel.CancelEventHandler(cb_BeforeDropDown);
//inside the eventhandler
myultracombo.Load();
//inside the Load method
datatable = DataUtility.GetAllRecords(tablename);
combobox.datasource = datatable;
If you store "the current value" as just the SelectedItem property, then it will probably not be an object that is present in the new list, since it will consist of completely new objects. What you will have to do is store an ID of the current value (if you're lucky to have a unique id) and then search the newly created list for an object with the same id (or whatever you use to uniquely identify an item, maybe just ToString()...).
Related
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);
}
I have a list box that is bound to an Observable Collection , when I the user add any new items to it it doesn't update itself until the app is closed and opened again.
(I serializes the content of the item source of this list and store it in Isolated Storage)
The only possible solution until now is to set the item source after adding the item in every method that allow the user to add any item but this isn't possible while adding from other pages as I can't access UI elements directly. Any help ?
I solved it ! In the Deserialize method I was pointing to another list (the one that has the result to Deserialization) and that damaged the binding.
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/
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.
After rendering full grid I need to change data context of selected Row since initially "simple" objects are filled as data source and when single item is selected (looking at RowDetailsVisibilityChanged event), then I want to change DataContext to complex object, that shows much more info in details than in collapsed row.
Using GridViewRowDetailsEventArgs.DetailsElement.DataContext seems to do the trick for Details element that is expanded below row on selecting, BUT Header (Columns) stay the same and values are not updated when changing GridViewRowDetailsEventArgs.DetailsElement.DataContext or GridViewRowDetailsEventArgs.Row.DataCOntext .
(Imagine like column of collapsed row is bound to Name, where Name is "John", and when expanding, Row.DataContext is changed to to object with property Name with "John Dough", but column still shows "John").
Ok i found a solution and it seems to be pretty simple.
so ... you hook up event handler to RadGridView.RowDetailsVisibilityChanged and in event handler itself you change Item property of provided Row:
private void OnRowDetailsVisibilityChanged(object sender, GridViewRowDetailsEventArgs e)
{
e.Row.Item = (my New Data);
}
Only problem right now is that row is no longer clickable (details no longer expands when selecting it).