I have a combobox in my WPF app that is databound to my list of objects in my View Model. When the user makes changes to the selected object and then selects another item before saving, I need to clear the changes made.
I thought I could use dataContext.GetChangeSet().Updates.Clear() but for some reason the collection is read-only.
I've also tried to use dataContext.Refresh but this doesn't work either as the object doesn't exist in the database, I created it manually from an SP.
Please help. thanks.
As well as using Marc's approach using DeleteOnSubmit (or DeleteAllOnSubmit) to remove the inserts, the following will actually undo any updates aswell:
// clears any updates.
ChangeSet changes = dataContext.GetChangeSet();
dataContext.Refresh(RefreshMode.OverwriteCurrentValues, changes.Updates);
Your best bet is probably to re-query into a separate data-context. You can negate an insert (from the change-set) by using DeleteOnSubmit (and the reverse), but I'd rather not, myself.
Related
I have a DataGridView, which has some DataSource. I need to filter the items in the DataGridView, based on some criteria the user specifies.
The problem is that the data is on a very slow database. For many of the items I can filter on information which is stored on the items themselves (which is quick), but sometimes I need to query the database to figure out wether or not a row should be visible.
Hence, I use a BackGroundWorker in the following way:
I make a copy (using CopyTo) of the rows in the DataGridView and pass this to the RunWorkerAsync method
In the DoWork method, I check each of the DataGridViewRow elements in the array. Sometimes I can simply look up the information in the row(E.g. read column 2 on the DataGridViewRow), sometimes I need to query the database.
Each time i know wether or not a row should be visible, I send a tuple consisting of a row number(Simply the position in the passed array of DataGridViewRow elements) and a boolean indicating the visibility to the ReportProgress method, which sets the visibility on the DataGridView.
The reason for copying (using CopyTo) is to avoid accessing the DataGridViews RowCollection from another thread.
All this works fine, but I am really wondering if this is a really bad way to do it.
Is it a really bad practice to operate on a RowCollection like this?
If it is okay, is it necessary to use CopyTo? The reason I do it is because lists are passed by reference, and I wanted to avoid accessing the UI from a seperate thread.
Thanks for your time.
I think your GUI is too tight to the database for a background worker.
In general I prefer to use BindingList<T> to bind the grid to, and manipulate the list instead of going through database. But if I have a fairly big amount of data to retrieve from database then I might enable the "virtual mode" of the datagridview, and again make use of the BindingList<T>.
Hope this helps.
EDIT1: Of course you can use filtering directly over your DataTables... but then maybe you should not involve the background worker.
EDIT2: I see BindingList<T> as a chance to bind the view to a model, and not to the data layer directly, which in general is better because separates data layer of presentation layer. Even more, you could create a view-model from the model to bind the grid to (MVVM pattern). But really depends on your project.
Presently In my application , on click of grid row , i fill the control of the page with the grid row entries. I have a UPDATE button to save the changes . But even if the don't modify any control values and click on Update button , updation will be done with same values. that triggers a entry to log table .
How can I make the form to call the update only when the values of the controls are different than what is being loaded to them when i click grid.
UPDATE :
Application is not using any pattern like MVVM . the structure what is being followed is very slimier to win forms except the UI . For db interaction ADO.net . It was built already when i joined to this project & even I am new to wpf.
Can anyone help me out ?
I think that you need to do some change tracking on the Entities displayed in the grid. Whenever an Update is executed you check the state of the entities and only update those entities where it's needed. Basically you need to intercept at the level of Property Setters to keep track of changes in the entity. think about:
Using a base class that has some functionality for keeping track of the state of an entity. Very simple: a Boolean hasChanged or more "complex" an Enum with Added, Modified and Deleted or something.
Derive other entities from this base class
Work with public properties and private backing fields to intercept property modifications
When property modifications are executed store the information in a Boolean or Enum in the base class
When the update is initiated by the user loop through the entities presented in the Grid and pick those that have changes and send them to the database.
Some helpfull theory about this might be:
Change tracking on businees objects
Using Properties C# programming guide
ADO.NET Self Tracking Entities
I don't know from your question how tightly the coupling is between the user interface and the database (ADO.NET DataTables or so...). The idea presented above requires some "decoupling" of things. But, is a good basis for further functionalities in your application and can give you some ease of work, clear framework, improved maintenance and might increase performance.
I believe the easiest way to do this is to add a handler to controls, that are used to get user input, that will set some boolean property, e.d. RowWasEdited, to true. Then check this property on UPDATE button click event, do neccessary actions, and set it to false.
But I'm sure that there is something more elegant than this.
I was just after peoples opinion on when the best time to save an object (or collection of objects) is. I appreciate that it can be completely dependent on the situation that you are in but here is my situation.
I have a collection of objects "MyCollection" in a grid. You can open each object "MyObject" in an editor dialogue by double clicking on the grid. Selecting "Cancel" on the dialogue will back out any changes you have made, but should selecting "ok" commit those changes back to the database, or should they commit the changes on that object back to the collection and have a save method that iterates through the collection and saves all changed objects?
If i have an object "MyParentObject", that contains a collection of childen "MyChildObjectCollection", none of the changes made to each "MyChildObject" would be commited to the database until the "MyParentObject" was saved - this makes sense. However in my current situation, none of the objects in the collection are linked, therefore should the "Ok" on the dialogue commit the changes to the database?
Appreciate any opinions on this.
Thanks
Generally it should save when the user thinks it is saving. In this case, yes, OK should save the objects. While I'm sure there are exceptions, I've never run into a situation where a user expected something not to be permanent once they clicked "OK", unless you also have a separate save button elsewhere on the same screen.
It really depends on your and the users needs, but as a user I would assume that it will be persisted. To make everything much more easier for the user (and more complicated for you) you should provide an undo functionality.
If the lower level dialog does the saving, I'd give it OK / Cancel buttons and just have a Close button on the higher level one (with additions / deletions being applied + saved as they're done), otherwise OK / Cancel buttons on both levels would be my preferred approach - with a cancel at either level 'doing the right thing'.
I've always been an advocate of the "dumb presentation layer" approach; So you'd have a Thing class that is editable in a ThingEditor - the ThingEditor merely reports whether the end user selected accept or cancel - the opening presentation object can make the decision as to when to persist or not. By having a dumb editor, differing consumers of the editor can use it in different ways, so...
Along these lines (and to agree with Karussel's answer) I would say that editing a topmost object (even if it is in a collection) is typically when an end user/customer might expect the save to be committed, so do it then; But for when you're editing sub objects in collections, I'd not persist those changes until the parent is requested to be persisted.
How is data binding in C# WinForms supposed to work when you have a Save button? I don't want the data updated until I press Save!
I have two forms (list and detail) backed by a BindingList<T> collection and my custom object from that collection, respectively. I can bind each form to the list or object appropriately. However, any changes made in the detail form are immediately reflected in the list form - I don't want to save the changes and update the details shown in the list until the Save button is pressed.
Is data binding designed to support this? Is there a common pattern for doing so?
Whichever way I look at it, binding doesn't seem to be able to support this scenario. I've considered the following:
Pass a clone of the object to the detail form, but then I have to reconcile the changes on Save - changes may have been made to the copy in the list in the meantime.
Implementing IEditableObject and calling EndEdit on save almost works as I can prevent the list being notified of the changes made until Save is pressed, but if something else causes a refresh the list is updated with the interim data.
I'm currently left with dispensing with data binding in my detail view, and doing it all manually. Which is rather annoying.
Data binding really wasn't designed for this kind of thing, unfortunately.
The best solution we've found here is to edit object clones, then reconcile the changes, as you mentioned. You may want to come up with a custom collection and/or object interface that helps you manage this type of thing.
Even if the cloning method is slightly more work up front, it's going to be wayyyy less complicated and frustrating than using IEditableObject trying to catch all the possible events that update the data. Not only that, it's a more straightforward approach, and you won't end up with spaghetti code.
If you are set on using a binding list, your best bet would be to implement IBindingList to create the functionality that you desire. It may also be possible to pull this off by simply inheriting from BindingList and overriding the appropriate methods to change the binding list's behavior.
http://msdn.microsoft.com/en-us/library/system.componentmodel.ibindinglist.aspx
If you are not set on using a binding list, it is probably best to do the data manipulations manually based off of the control's events.
Best of luck.
I have a GridView which I am binding to my service layer.
I want to be able to allow the user to edit the grid, but I do not want to save the grid as the user is clicking update on each row. I would like to update all of the edited/added/deleted rows when the 'save' button for my entire form is submitted.
I have my service layer configured, and the GridView calls update on a per row edit basis, however I want that to happen all at the end when clicking save.
How can I maintain my ObjectData sources references to update, insert, delete but instead of on a per row basis be able to call a save on everything all at once?
Thanks!
If you're using an object data source, then the behavior of the object bound to the object data source is up to you; it doesn't have to save to the database right away. If you want, you can build the database commands you want to execute, then cache them somewhere until the save button is clicked.
Object data source objects should be static or stateless, so you can't cache there. However, this sounds like a reasonable use of Session cache.
Here is a tutorial on asp.net/learn for wrapping updates in a transaction:
http://www.asp.net/Learn/Data-Access/tutorial-63-cs.aspx
The example uses GridView and ObjectDataSource.
This may or may not be useful with subsonic, but it may help others with a similar problem.