Most efficient way to retrieve/update an object from a collection? - c#

I'm working with a silverlight datagrid that is bound to an observable collection of a business object.
We do not support inline editing of the objects within the grid but we do display a corresponding editing panel for the user selected row.
When the user submits the edits from this panel, I'm persisting the changes in the DB but I'd like the changes to also reflect in the grid.
I know that through the use of the observable collection and notify property changed that if I change the object that the selected row is bound to, the changes will display in the grid.
However, since I'm not inline editing, I need to search the observable collection for the object and make the change to the business object's instance in the observable collection.
I'd like to avoid having to loop through the collection to find said object but I'm worried this is the only real way.
There's no other more efficient, less performance-heavy way that I'm not aware of to retrieve an object from a collection correct? Other than simply to loop through until I hit it?

can you bind your edit grid to the selected item of the display grid? Since they are references this will push/pull changes into the observable collection which can then be persisted.

after having some critical exceptions happen that i couldn't keep track of i decided to avoid the databinding to the edit panel and go with Jeffrey L Whitledge's suggestion.
i'm maintaining a reference to the object displayed in the panel and with the notify changed, when i the user submits the update panel and i persist the changes to the business objects, i'm setting the changes to the grid row object that's bound.
thx guys

Related

What is the best practise for updating a collection of items (ie: in a data grid) when refreshing details from a web service?

This seems to be a problem that I encounter regularly: I have a list control, in this case a DataGrid, and the items in the control come from a web service. My application regularly asks the web service for the latest list of items. Compared with what my application currently has, the resulting list may have additional items, fewer items, or different details for existing items.
How do I update my control (ie: my data grid) without:
1) De-selecting the user's currently selected items.
2) Resetting the ordering that the user may have set on various columns.
3) Doing anything else that makes it jarring for the user.
4) Incorporating too much code, turning it into an unmaintainable mess.
Am I simply going about this whole thing wrong? It seems to me this scenario should be simple to address with something as versatile as WPF.
My current thinking is to use INotifyPropertyChanged on each item, and an ObservableCollection. Then, for each item in the list, update every property when we do the refresh (adding and removing items from the collection as necessary).
You are right, use ObservableCollection
1) De-selecting the user's currently selected items.
You can use either CollectionViewSource.GetDefaultView(rootElem.DataContext).Current or create a SelectedItem property, and bind it to the UI element. I prefer SelectedItem because it is less view related. For deselecting just set it to null.
2) Resetting the ordering that the user may have set on various columns.
You can easily swap two elements in ObservableCollection, and that change immediately will appear in the view.
var tmp = myObsCollection[i];
myObsCollection[i] = myObsCollection[j];
myObsCollection[j] = tmp;
Also you can use keep order property in your items, configure sorting in CollectionView, and just rearrange orders when needed and call view.Refresh();
3) You don't need to update all properties for updated items, just find the correct item index and replace it with new one, WPF will update automatically
myObsCollection[fIndex] = updatedItem;
Use the same logic for delete/add elements

Temporarily switch off bindings in WPF

The title of the question is bad, feel free to update it.
I have an observablecollection that generates a user control whenever it an item has been added to it.
However there are times where I just want to add to the collection and not have it create a usercontrol. Is there a way around this problem? Thanks.
Create a collection view around the observable collection and bind the UI to that. The collection view will have a filter so that only items you want in the UI are filtered in

How do I keep the selection in ListBox when reloading ItemsSource

I am experimenting with WPF and MVVM in our system. However iam having a problem with keeping things selected in lists using only MVVM ( without doing extra CollectionViews ).
What i currently have is the list
ObservableCollection<ReservationCustomerList> Customers;
And then a property storing the selected Customer
ReservationCustomerList SelectedCustomer;
In my opinion now, when the list reloads (actually from another thread async), the selection should be able to be kept, however this does not happen.
Does someone have a nice clean way of achieving this ?
The way we did it was that we did not replace the collection. We added/removed the entries and updated existing entries if required. This maintains the selection.
You can use LINQ methods like Except to identify items that are new or removed.
In case the reloaded list still contains the last selected item and you want that item to be selected, then you can raise the PropertyChange event for the property SelectedCustomer after your collection gets reloaded.
Please make your sure your viewmodel class implements INotifyPropertyChanged interface.
you can use the ICollectionView to select the entity you want.
ICollectionview view = (ICollectionView)CollectionViewSource.GetDefaultView(this.Customers);
view.MoveCurrentTo(SelectedCustomer);
in your Xaml the itemsControl must have IsSynchronizedWithCurrentItem=true
or if the ItemsControl has a SelectedItem property you can simply bind it to your SelectedCustomer Property.
When you "reload" your collection you basically replace all values in it with new values. Even those that look and feel identical are in fact new items. So how do you want to reference the same item in the list when it is gone? You could certainly use a hack where you determine the item that was selected by its properties and reselect it (i.e. do a LINQ search through the list and return the ID of the matching item, then reselect it). But that would certainly not be using best practices.
You should really only update your collection, that is remove invalid entried and add new entries. If you have a view connected to your collection all the sorting and selecting and whatnot will be done automagically behind the scenes again.
Edit:
var tmp = this.listBox1.SelectedValue;
this._customers.Clear();
this._customers.Add(item1); this._customers.Add(item2);
this._customers.Add(item3); this._customers.Add(item4);
this.listBox1.SelectedValue = tmp;
in the method that does the reset/clear works for me. I.e. that is the code I put into the event handling method called when pressing the refresh button in my sample app. That way you dont even need to keep references to the customer objects as long as you make sure that whatever your ID is is consistent. Other things I have tried, like overwriting the collections ´ClearItems()´ method and overwriting ´Equals()´ and ´GetHashCode()´ didn't work - as I expected.

how to add items to datalist after postback without accessing database again

I have a DataList with a set of items (comments), users are able to leave new comments, so after they send a new comment I want to add it to the list. I know I can access de database again retrieve all data and call DataBind again or maybe cache the list of comments to avoid accessing the database, but that options are not possible, they impact on performance or memory, I Just want to access the Items property in DataList and add a new one, if it is possible with a Bind because I have a lot of properties to set, and even another DataList inside this one (replies for comments)
What's the best approach to solve this?
Presumably the client-side graphical control (your DataList) is bound to an object containing the list of items to be displayed. If the object was initially populated with a database call, and yet you now do not care if the database is updated, or do not care if the graphical display is out of synch with the database, and merely wish to add another item to the graphical display, you could simply add the new item to the underlying object to which the DataList has been bound, and invoke DataBind().

Is there a better way of updating a data grid then just adding and removing the datasource?

I have a List collection where UserPropDef is a custom class with a few public properties. I want to display the contents of this list in a DataGrid. So I set the DataGrid.DataSource property of my grid to the list and it displays the contents just as I want.
Now if I add or remove items from the list I want the DataGrid to update. I can't use a BindingList because this list needs to be serialized. I've tried calling the Update() and Refresh() methods of both the DataGrid, and the form and nothing seems to cause the DataGrid to refresh based on the current contents of the collection.
The only thing that works seems to be setting the DataSource property again. Yet when debugging my code I can see that after the collection has changed the DataSource property of the DataGrid is in fact still referencing the correct and updated collection.
Is there a better way to cause the DataGrid to refresh based on it's current DataSource?
My suggestion would be take what is behind door number 3:
Create a custom Serializable List that implements IBindingList (Or something that inherits from BindingList and fixes the Serializable issues. Check out Fixing BindingList... for ideas).

Categories

Resources