I have a DevExpress DxGrid bound to an ObservableCollection of viewmodels (based on SimpleMvvmToolkit).
The viewmodel has 2 properties exposed by itself (a string and a boolean) and a few other properties are exposed by its base class (ViewModelDetailBase), one of them is the model behind the viewmodel.
Everytime I use the grid to modify the contents of one of the properties (e.g. the boolean value), I get an error saying "The type xxx cannot be serialized.." (xxx is the type of the Model) followed by the suggestion to use DataContractAttribute to circomvent the issue.
I am not sure how and where to look for a solution. Maybe I should read up on it, but why is serialization needed here??
Anyway, I hope you can shed a light on this. I'd appreciate some pointers to get me looking in the right direction.
edit: Since the situation is too intricate to post the relevant code here, I made a sandbox project that reproduces the error. You can find it via this WeTransfer link.
Best regards,
~Rob
Thanks to great help of the Simple MVVM Toolkit community I found out that the solution was simple.
In Simple MVVM Toolkit, A viewmodel needs to be serializable because it gets cloned. This is to easily roll-back data when an action is canceled. The reason my viewmodel could not be cloned whas because its "model" property was missing a default (parameter-less) constructor.
There's no need to decorate the viewmodel and its properties with [DataContract] or [DataMember].
I hope this helps others.
Related
I work on a custom WPF Diagram Control. The control has a method that arranges the elements in the Diagram and I need to add MVVM support to call this method from my View Model.
At the moment I am a bit confused how to implement this and I hope that someome can point me to the right direction.
Maybe you need to rethink your concept. What needs to be re-aranged?
Think of ViewModel the logic behind a view and the view should be as dump as possible without any logic.
I assume also that the "arranges" method should be well tested and this could also be "easier" done on a ViewModel (if done right). Your best bet would be to place all logic in the ViewModel.
From the top of my head I could think of a DiagramViewModel with an ObservableCollection<ShapeViewModel>. ShapeViewModel can either be a base class or a concrete class which could also have some information about the location of the shape etc. The communication between the view models can be done via a Messenger (MVVM Light Messenger) or EventAggregator https://msdn.microsoft.com/en-us/library/ff921122.aspx.
If you still want to leave your architecture as you have it and want to execute a method on the view I would abstract it in a service. IDiagramUpdateService.
Look at following article which gives you good insights in communication between views and view models (and vice versa).
https://msdn.microsoft.com/en-us/magazine/jj694937.aspx
You'll find great information for both approaches.
HTH
Thanks for the quick response to my question.
I think my concept was a bit wrong, since the ViewModel should have no reference to the View.
What I would like to achieve is that I can place a button in the Main Window that calls the Arrange Method in the Custom Control.
I realized this by adding a RoutedCommand to my Custom Control.
And the Command Property of the button on the main window is bound to this RoutedCommand.
So the ViewModel is no longer involved in calling this method. It just manages the items that are shown in the Custom Control.
I have a project that gets data from a database and binds that data to some elements in xaml. I have added a button that fetches new data from the database and want to refresh the data bound elements in the xaml.
Now, I know the proper way of doing this is to implement the INotifyPropertyChanged events in the data class but I wanted to avoid this as there are so many properties. I figured out that simply calling 'this.DataContext = data;' after I have retrieved the new data from the database updates the binding in xaml.
Can anyone tell me what is wrong with this method?
Thanks!
Quite simply, if you don't want to implement the INotifyPropertyChanged interface, then don't use WPF. WPF is quite often a verbose language... it took me a while to get used to this. While there are mechanisms like Converters, Styles and Attached Properties that enable us to reuse code, you will often find yourself writing code that you've written before. Just get used to it, or change languages.
To summarise, you can't write effective applications in WPF without implementing the INotifyPropertyChanged interface.
If you don't use INotifyPropertyChanged interface you don't allow the binding mechanism to work since it wont know of any changes of your data.
The data binding is one of the most powerful tools in WPF if you dont use it you will have to write the propagation of the data changes between you model and the UI yourself like it was done in Winforms....
if its too hard to write the implementation for each property of each class in your than you can create a code snippet.. like prop/propdp
Advance apologies for the event-style explanation; there's a lot of factors that I feel all play a role of their own. WPF is not my native framework of choice, and it probably shows. :)
Old situation: I had a window with several controls. Depending on their selections, I used multibindings and a converter to determine whether certain controls needed to be shown that inform the user about the implications of their changes before they'd eventually confirm them by OK (or simply dismissed by using Cancel). This worked perfectly.
Problem: Too many controls as time went by, too much clutter.
Solution: Put stuff in different Pages so it becomes easier to browse for the user. In order to have changes-to-be persist as a user arbitrarily browses between the pages, I create these dynamically and put them in a cache (Dictionary<string, BasePage>, see below), from which they will be pulled as the user chooses them.
Consequence: I need to decouple the bindings to the notification controls as the different options are now on different pages.
Solution? I put a BasePage class in that exposes certain abstract read-only properties that define the various aspects that the window needs to know about in order to do its notifications. For example, a bool requiresReboot property defines whether the current state of things on that page requires a reboot to take (full) effect. A specific page implements the property based on its controls.
Problem: I do not know how to keep create a proper binding that properly gets updated as the pages are changed. I tried giving my notification controls a binding to the Dictionary<string, BasePage> with a converter that checks all pages and the relevant property.
Questions:
1) How do I create a proper property for this purpose? I presume I need a DependancyProperty as I did a fair bit of reading on MSDN, but I can't figure out how this fits together.
2) How do I make a link between my custom property so that it allows (multiple) control(s) on a page to change that property? Do I use INotifyPropertyChanged somehow? My old example bound against several CheckBox.IsChecked properties in XAML. I am trying to avoid putting tons of events (OnChange, etc) on the controls as the original code did not need it and I have been told it makes for a messy solution for as far WPF is concerned.
3) Finally, I suspect I may need to change my Dictionary<string, BasePage> class to a custom implementation that implements some sort of INotifyPropertyChanged but for Collections? Observable Collection is the term I am looking for, I believe.
I hope someone is able to bridge the gap in my understanding of WPF (property) internals; I would very much appreciate it. A basic sample would be even better, but if it is too complicated, just a nudge in the right direction will do. Thank you. :)
It's been a while since I solved this, and while I cannot remember the exact cause of the problems, there were a few different issues that made up the bulk of the trouble I ran into.
I ended up making the Property in question a non-abstract DependencyProperty in the base class; it was the only way in which I could properly delegate the change notifications to the interface. Derived classes simply ended up binding it to their controls (with a proper Converter in the case extra logic was necessitated).
As Dictionary<string, BasePage> does not support any sort of change notification, I made an extra collection of ObservableCollection<BasePage> which I used for binding purposes.
However, such a collection does not propagate a change event when items inside of it has a property changed. Since this situation required that, and I was binding to the collection itself in the context of a property that does not have a Master<->Detail relationship like a DataGrid (which basically add their own OnPropertyChanged handlers to the binded object), I ended up subclassing a VeryObservableCollecton<>. This one listens to its own items, and throws a proper change event (I think it was an OnPropertyChanged from the INotifyPropertyChanged interface) so that the binding (or in this case a multi-binding) would refresh properly and allow my interface to update.
It is hardly the prettiest code, and it feels over-engineered, but at least it allows me to properly bind the UI to the data in this manner.
This is somewhat of a followup to my previous question, where people pointed me in the direction of MVVM.
I'm trying to understand exactly where the work is supposed to go in this framework. My view contains a textbox into which the user is meant to input a URI.
As far as I see, I have two choices:
Bind to a Uri object in my ViewModel, using a converter and validator to check if the URI is valid and convert it if it is. The ViewModel then ends up with either a valid Uri, or DependencyProperty.UnsetValue. (I am using something like this as a combined converter/validator; is this good MVVM practices?)
Bind to a string in my ViewModel, and do the conversion/validation as necessary for the ViewModel's code. I'm not entirely sure what the code is for having the ViewModel tell the view that the URI-string is invalid, though, and displaying appropriate validation errors.
I guess generally the question is about how and where to handle potentially invalid data in the MVVM framework. This doesn't seem to be covered in any of the basic introductions to MVVM that I've been browsing through. Thanks for your help in getting this all straight in my mind :).
In my opinion, you should have your validation framework, validate the input from the user, once it's confirmed as valid, is should be bound by a converter to a Uri property on the ViewModel.
It all depends how you setup your validation, but I would suggest that your validation should come before properties being set on the ViewModel.
Hope that helps!
Ok,
So I have been stalled in my latest non-work project, trying to use WPF. I am just frankly annoyed at databinding. I thought it was supposed to make things simpler by binding data directly to the UI. But the more I learn about having to implement INotifyPropertyChanged to get things to notify the UI if they changed, seems to make the whole thing counter productive.
Am I missing something? It seems like a bunch of work and having to make the classes implemented INotifyPropertyChanged seems like a fishy way to get databinding to work.
What am I missing? I must be missing something. Please enlighten me into how to make databinding easy, or at the least straightforward.
If you want the UI be notified when the underlying data source changes, then you need some sort of notification mechanism. For WPF, INotifyPropertyChanged is that mechanism.
It's the same in Windows Forms as well, but Windows Forms also supports the old notification mechanism, where you have an event with the name <Property>Changed.
However, neither of these required these mechanisms if all you want to do is bind to the data once and display it.
If you are ok with not receiving notifications, then just bind to the data source and it will work.
Truth be told, I haven't seen that it was that bad, and think it a highly workable solution.
Take this simple, Data Model object:
Public Class SimpleItemViewModel
Implements INotifyPropertyChanged
Private _item As String
Public Property Item As String
Get
return _item
End Get
Set (value as string)
_item = value : OnPropertyChanged("Item")
End Set
End Property
Protected Overridable Sub OnPropertyChanged(propChange as string)
Raise Event PropertChanged(me, new PropertyChangedEventArgs(propChange))
End Sub
Public Event PropertyChanged(sender as object, e as PropertyChangedEventArgs)
End Class
That is easily bound to a simple Textbox via:
<Textbox Text="{Binding Item}" />
additionally, if I wanted to have a DIRTY flag, I can easily put the flag being set in the OnPropertyChanged sub, and easily determine if I need to save any user changes or not.
I have found it easiest to have a set of classes which rest between the Data Access layer and the UI which holds this stuff. You can even have your Business Logic and DAL pass these classes around rather than the atomic values.
Implementing INotifyProperty changed is not particularly difficult, seeing as it only has one member.
If you don't expect changes in the underlying object then don't worry about INotifyProperty changed, and use a Binding with Mode=OneTime.
If the underlying object can change and you want the GUI to reflect those changes, then how else can this be achieved without the kind of notification that INotifyProperty changed provides? It's not reasonable to expect a bound item to poll its binding's source.
Personally I've found WPF has taken some time to get to grips with, but now that I'm gaining comfort I'm finding it incredibly powerful and enjoyable to work with. I encourage anyone who's finding WPF challenging to stick with it.
Binding in XAML is quite easy, however, dynamic WPF data binding in code is painful and confusing.
DataBinding is the only way to implement a model-view pattern in WPF/Silverlight. Your models can be UI-stupid by implementing INotifyPropertyChanged, which isolates them from the UI. It also saves a lot of UI code when stuffing information into the UI.
Another benefit that I enjoy is the ability to further bind child controls with the same data by using the { Binding } shortcut.
First, INotifyPropertyChanged isn't the only way to get data binding to work - dependency properties work too.
Second, INotifyPropertyChanged can be implemented with just one line of code in your entity class, if you use AOP - you don't actually have to do all those notification calls yourself.
Overall, I'd say data binding is a great boon, especially when you're doing code generation to make automatically bound controls from some data source.
If you're looking for a good way to think about structuring your data binding, then aim to set a DataContext on your logical tree only once, then use binding paths to populate the various parts of your UI.
Be as declarative as you can in your binding. Let the template system do it's job and make heavy use of DataTemplates that specify explicit DataTypes.