i'm new by programming in wpf and c#.
I have a litte problem with an datagrid.
The grid is binding on a EF-Table.
I can see and change all fields and save the changes to the database.
The problem is. When i save the data via context.savechanges to the SQL-Database, the Trigger on the SQL-Server-Table modified some fields in the record.
When is Reload the Entity for the currentItem after the save-command, i can see the modified data in my Entity but not in my UI.
I must make a datagrid.items.refresh to see the changes. But the refresh is not performant and i loose the current cell position.
I need a way, to push any changes from SQL-Server on the current record on the fly to the UI after change on field in the UI.
Have anybody some ideas?
In an simpel TextBox-Element on a Window, i can use the BindingExpression to push the changes via binding.UpdateTarget. But it's not possible in DatagridTextColumn.
Your entity class should implement the INotifyPropertyChanged interface and raise change notications whenever a data-bound property is set to a new value.
If you are using auto-generated entity classes, you need to modify the template that these are generated from:
How to get property change notifications with EF 4.x DbContext generator
Or you can bind to your own wrapper classes that do implement this interface:
Implement INotifyPropertyChanged on generated Entity Framework classes
Related
When I try to insert or update data in my WPF usercontrol datagrid, the data is not being saved to the corresponding property. This is being caused by (at least so I believe) my bound property having the [NotMapped] attribute, all the other properties without the annotation are working correctly.
The data which need's to be updated is inside a DataGrid component which is bound to an ObservableCollection with the appropriate model. Inside the model there are several properties with the [NotMapped] annotation, these properties should be excluded in the creation of the table (model) in my database, though I do need them for binding input, hence the use of the [NotMapped] annotation.
Since the data is bound to a ObservableCollection I can't add the [NotMapped] properties to the usercontrol directly (so they wont be a part of the model).
Below an example:
Part of the XAML
In the image below we can see 1 property (pBreedte) which is 1 of the NotMapped properties, as well as the itemsource of the datagrid:
UserControl Code behind (part of it)
Part of the model which is used in the ObservableCollection
The model is being used for EF6 (code first).
Is there any way that the NotMapped property values can be stored / saved?
The easiest would be to just include the NotMapped properties in the database (so removing the annotation completely) but I am trying to avoid this.
More background information
The NotMapped values are added because they function as a placeholder property. Initially I had several decimal properties bound to the datagrid directly, but textboxes can't handle decimal values very well (WPF validation rule preventing decimal entry in textbox?). So I created a string placeholder for those decimal properties, when the form is being saved the decimal properties are being set to their string placeholder counterparts. This way the user can add decimal places without having to use a delay, value converter or anything.
If you don't need that information in your database, then don't store it - meaning your approach is good.
What I think here what might be the problem is that you are using your entity/database model as UI model.
I would suggest that you try to introduce a different model for the UI controls and user input. The models might seem to be duplicate at the beginning but while you are working on your application they will start to differ, but still describing the same items just form different perspectives.
Example:
Entity model has a class CarEntity. It is a pure POCO class, having only the needed properties that will contain the data in the corresponding table.
Ui model has a class CarUi. It has the same properties as the CarEntity. They are loaded and mapped from the database (from the CarEntity) shown to the user. If the user changes something, the diff values are mapped from the CarUi to the CarEntity and then stored to the DB.
With this separation of models approach, you should not face the issue where one constraint (mark column not to be stored in a table) influences other functionality.
Hope this helps,
Cheers and happy coding!
I have windows phone 8 app which displays a persons pic and his details sent from server (something similar to a contact book).
The way I have implemented this, is by storing images from server in Isolated Storage with a unique name, and then adding this unique name and person's information in database.
I implemented the GUI, by binding the database to a LongListSelector (using Observable Collection). LongListSelector's item template has an Image control and I use ValueConverter class to translate the unique name from database to the physical location of the image. When server sends an update to personal information, I can simply update the database and data binding will update the UI automatically. Until here everything works perfectly.
Now I have this scenario :
When the server sends an updated image, I can only update the isolated storage. How can I let the GUI know that image is updated? I am not sure how to make use of databinding here, since the image name doesn't change and there is no update process in database table.
Is there a way other than reloading the entire collection?
I guess that the class bound with the UI is acting like a ViewModel and is implementing the INotifyPropertyChanged interface or some derived class (ViewModelBase for example if you're using MVVM Light).
In that case, you should raise the ProperChanged event (or call the RaisePropertyChanged method in MVVM Light) with the name of the property bound with the image control in order to notify the UI that the data has changed. The converter will be called again and the image will update.
I'm creating a simple database application in C# WPF using MVVM as Relay Commands and databinding. For in-memory storage of database content I use ObservableCollection, which is binded to the Datagrid as follows:
<DataGrid ItemsSource="{Binding Path=Softwares, Mode=OneWay}" SelectedItem="{Binding Path=SoftwareSelection, Mode=TwoWay}">
when the item is selected user can chose to edit it. For editation a form is opened with a bunch of textboxes with the data of given entity. All the fields are validated using IDataErrorInfo, unless all textboxes are valid, the ok button is not enabled, and therefore no changes can be saved to the collection and to the database.
Here is how the example textbox looks like:
<TextBox Text="{Binding Name, Mode=TwoWay, ValidatesOnDataErrors=True, UpdateSourceTrigger=PropertyChanged, ValidatesOnExceptions=True}"/>
But the tricky part is, in case I change some values in textboxes and then close the window, the new values are propagated to the ObservableCollection, which I don't want to. Do you have any idea, how to prevent such behaviour? I would like the databinding work only after clicking the button. Otherwise the databindng works well, so as the button (dis/en)abling and reflecting changes to the database and to the collection after clicking. Both views are serviced by different ViewModels, data between views are passed by firing events.
I tried to add to the DataGrid UpdateSourceTrigger=Explicit to the ItemsSource binding, but didn't help. Perhaps, I'm missing some application logic?
Thank you very much for your help.
This is where most WPF developers make mistakes of assumptions!
In MVVM dirty data can be stored in the ViewModel and that's what the layer of VM is for! It mimics the View from Model's perspective and because View is in error, the ViewModel would also be in the error. Thats perfectly valid.
So having said that, the question remains
How will you NOT allow the temporary / dirty data to flow to your
ObservableCollection?
Two ways...
If your ObservableCollection is specific to your model class (say MyItem) then if your Model class (MyItem) is an Entity class \ DAL class \ NHibernate class create a wrapper of MyItem class called ViewModelMyItem and then instead of ObservableCollection<MyItem> use ObservableCollection<ViewModelMyItem>.
This way dirty data from your View would be inside ViewModelMyItem and it can only be legitimately flown back to your model class (MyItem) ONLY when Save button is clicked. So that means in Save Command's Execute() delegate you can copy \ clone the ViewModelMyItem's properties into Item's properties, if validations in ViewModelMyItem are fine.
So if Item is an EntityType class / NHibernate class / WCF client model class, it would always only valid data as ViewModelMyItem is filtering the temporary / dirty information upfront.
You could use Explicit binding model. It stops the TwoWay data to flow back to the sorce Item unless BindingExpressions.UpdateSource() is explicitly called.
But according to me, this defeats MVVM in straightforward way because ViewModel will not have what UI is showing! Still however you can use *Attached Behavior * to govern explicit binding by staying in MVVM space!
Let me know if this helps!
You're better off putting the code into the domain object's property setter. Then synchronize with the visuals by triggering the NotifyPropertyChanged handler.
More on this topic:
http://msdn.microsoft.com/en-us/library/ms743695.aspx
http://msdn.microsoft.com/en-us/library/system.componentmodel.inotifypropertychanged.aspx
Setting the Binding Mode to Explicit should require you to call the binding expressions UpdateSource() method to send changes back to your model. Because you only mentioned that you set Explicit on the DataGrid's binding, I'm guessing you only need to make sure that you have that mode explicitly set on any property that is being bound directly back to your model. Such as your TextBox's Text Binding, in the case above. That will likely fix your problem but require you to call UpdateSource() on each target's BindingExpression one way or another.
If you're using one of the mainstream ORM's (EF, Linq to SQL, etc), then chances are your Entities automatically implement INotifyPropertyChanged and INotifyPropertyChanging. Because you are sharing a reference to your single instance, all changes in your edit will be reflected in your main view and anything else Binding to that instance. As a dirtier alternative, you can just create a separate instance of the same type and manually copy the values back over when the window's dialog result is true.
The first approach requires you to manually update the bindings, the second approach requires you to manually update the values from the Edit's instance.
With some more code, I can help with your specific approach.
I have a viewmodel that has an EF object as one of its properties. The view has several text boxes wired up to that property via Text="{Binding Path=MyEFTable.Column1}". I'm using the MVVM Light toolkit so my viewmodels inherit ViewModelBase and subsequently each property calls RaisePropertyChanged() when changed.
I have noticed, however that changing MyEFTable.Column1 does not set off any changes in the viewmodel. I thought that EF objects tracked any changes, so I assumed that changing a column value in an EF object would cause the EF object itself to be changed. Is it no longer tracking changes since I am essentially copying the query result into a new MyEFTable object?
Does your bindable objects implement INotifyPropertyChanged or it's container, like ObservableCollection?
Are you rising the event?
Using a view model is only the start. First thing you should check is to see if the Column1 Property is being updated after the editing occurs. If a TextBox, the UpdateSourceTrigger default value is LostFocus. Maybe you can try change it to PropertyChanged.
If the value is updated in your MyEFTable.Column1 you're done. If not, again, something is using the INotifyPropertyChange.
Add more info and maybe the issue will be clearer.
HTH
C# How do I use an even to get my GUI update on change of an object?
I have a GUI program that creates an object and displays the object in a data grid through reflection.
When the user updates the information I want to be able to verify the new information and send feedback to the user. I have a method that does the verification of the information, I just need to figure out how to update the GUI with the new information.
thx.
Another general approach would be to support IObservable on your object, and IObserver on any classes (such as user interface elements) that wish to be notified of changes to your object. You can have any number of observers of changes on your object. It's a little more work than the "out of the box" data binding on controls such as data grids, but I would say more flexible.
Perhaps you could be more specific or show some code, but check that each Column Object of the .Net Datagrid has a property named DataPropertyName, which binds by reflection to the property of your objects, it should work..
Other thing is to implement the INotifyPropertyChanged on your objects, and Refresh the Grid on the PropertyChanged event.