I've extended my domain class on the silverlight client side in a partial class. Specifically, I've added a RelayCommand property that I will be binding a button to. The RelayCommand property needs to be initialized, and so it would seem that the best place to do that would be in the OnCreated partial method.
However I gather that when the object from the server is materialized on the client side its constructor is not called (which seems totally wrong headed to me!) Since it's constructor is not called, it's not calling the OnCreated Method.
Is there a config or a convention for getting this OnCreated partial method to be called as the objects are materialized?
DataContractSerialization does not call the constructor of the objects that it deserializes. This decision was made because with the previous serialization methods in .NET having to always have a default constructor on any object that was going to be serialized was a problem. This is not specific to RIA Services, it was a design decision made when WCF itself was created and there is no configuration to change it.
You can find more information at http://blogs.msdn.com/b/carlosfigueira/archive/2011/09/06/wcf-extensibility-serialization-callbacks.aspx as well as examples of how you can use [OnDeserialized] to replicate the effect of the constructor being called.
However, there is a second issue that may cause you problems. Entities get constructed all the time. For example, any time you call TEntity.GetOriginal a new detached entity is being created and returned from the method. That makes trying to do anything like configuring a RelayCommand a potential performance and stability problem. You are probably better off configuring RelayCommands at the DataService or ViewModel level instead of inside the entity itself.
The partial method OnCreated() is only called when you instantiate an Entity using its default constructor.
If you want to initialize your loaded entities you have to override the OnLoaded method. A boolean is passed to it that specifies if the entity was loaded first time or not.
Related
I just want to ask if it's OK to access the ViewModel's data in the View backend?
Basically I just need a check to see if a ViewModel's property is set (which gets set when the user selects something), and if it's not I'll just redirect the user to another View telling him he needs to select something first. Is this a poor-design practice or is it OK, just for a minor check like this? Really don't want to implement a static class and extrapolate the data to it, and check it instead.
Another question tightly related to this, is can I call a method from the View (when the View is closing), that unregisters that particular ViewModel from the IoC container (this ViewModel isn't singleton). The alternative is to send a message from the View to the ViewModel when the View is closing, and when the ViewModel gets that message it unregisters itself. The problem I'm trying to solve with this is that, every time that ViewModel is requested it has to be a new one, but my IoC container caches them, making my program a memory hog. All of the ViewModels get released on application exit, meaning x ViewModels will still exist in the cache even though they're most likely not needed.
Basically I just need a check to see if a ViewModel's property is set (which gets set when the user selects something), and if it's not I'll just redirect the user to another View telling him he needs to select something first. Is this a poor-design practice or is it OK, just for a minor check like this?
It does not seem to be wrong to check the value of some ViewModel property and reflect the changes on the View side. The View state could be "bound" to the ViewModel state by the WPF data binding mechanism: Binding, Triggers (Trigger, DataTrigger, EventTrigger), Commands (including EventToCommand), etc.
But sometimes it is useful to handle ViewModel state change by the ViewModel itself using UI Services. For example, IWindowService interface can be introduced to allow to open windows from the context of the ViewModel implementation.
Another question tightly related to this, is can I call a method from the View (when the View is closing), that unregisters that particular ViewModel from the IoC container (this ViewModel isn't singleton).
...
The problem I'm trying to solve with this is that, every time that ViewModel is requested it has to be a new one, but my IoC container caches them, making my program a memory hog. All of the ViewModels get released on application exit, meaning x ViewModels will still exist in the cache even though they're most likely not needed.
It seems to be strange that the described dependency container "cache effect" exists when the registration is specified as "resolve per call behavior" (not "singleton behavior"). Please check that the registration is specified as "resolve per call behavior" (for example, PerResolveLifetimeManager in terms of Unity Container Lifetime Managers).
Update
The ViewModel lifetime problem exists because SimpleIoC container is used.
I would like to recommend using another dependency injection container (with appropriate lifetime management) to make the implementation less complex and error-prone.
But, if there is a strong need to use SimpleIoC container, some kind of the ViewModel lifetime management can be implemented using:
SimpleIoc.Default.GetInstance<ViewModel>(key); method call to resolve an instance of ViewModel;
SimpleIoc.Default.Unregister(key); to un-register the instance when it is no longer needed (Closed event, etc).
The implementation can be found here: answer #1, answer #2.
In my view-model i have an command which implements print operation using PrintVisual of PrintDialog class . As i don't have the access to the view i cannot print it .how should tackle this ?
Is there an easier and better approach?
I think your solution would be to pass a service class in that performs the work of printing the grid, showing a dialog, and whatever work is required to get the job done.
In MVVM, most of people use dependency injection to do this. You would create another service with the same interface for your tests to use that wouldn't block execution. The service, in this case, is a view layer service, and should have no dependency back to the viewmodel. The only thing the viewmodel knows is that it has a service interface to call into, and the only thing the service knows about the viewmodel is the interface it implements for this interaction.
I read this Wikipedia article that has helped me in the past:
SOLID - Wikipedia
Let me know if this makes sense.
This is how i solved it.
I created an event in my viewmodel. Raised the event here whenever i want to print operation.
I defined my listener method in the mainwindow.xaml (this is where i have defined my content presenter , and all the data templates are being assigned to this contentpresenter.content)
In this listener method i am calling the print operation using PrintVisual of PrintDialog Class.
!
Loosely said, the various components in a MVVM pattern are
Model: this represents the data send by the server and sent back to the server. this contains no state related to display of the UI
ViewModel: this is constructed from one or models. this contains state meant for UI manipulation (is the button enabled or disabled). all logic meant for UI manipulation is stored here. this layer has no dependency on any UI framework (no jQuery calls)
View: this has tight coupling with the UI framework/underlying UI controls. One view observes one and only one view model. A view model can be observed by one or more views. The view is responsible for doing two-binding with the view model.
A presenter/coordinator: While not a part of the traditional implementation, in its absence the view model ends up with way too much responsibility. This guy helps coordinate making ajax calls (get/post), listening to events on the global event aggregator etc
Standalone Backbone has no concept of view models and data binding. In that scenario, the data returned by the server can be modelled as Backbone.Model objects. The bindings are done manually and a POJO can be used for view-model syncing.
If I wish to use Stickit for data binding, it appears that the view model needs to be an instance of Backbone.Model. Chiefly because the bindings work within the context of a Backbone.View and a Backbone.View expects a Backbone.Model object to be present as a property of the view. Also, a Backbone.Model raises change events and what not. I assume it will be difficult to observe a POJO. Again, this is my understanding from reading the Stickit docs. Please correct me if I am wrong.
A Backbone.Model has other methods on it that don't make sense from the point of view of a view model, like save, fetch etc. I was reading up on another mvvm library, Knockback. It can transform a Backbone.Model into a Knockout.js view model. Instead of passing in a full fledged Backbone.Model, it can also accept any POJO that has get/set methods and raises change events when the properties have changed.
Does Stickit have a similar contract wherein I can pass in a POJO that has get/set methods and raises change events? What is the recommended usage?
There's nothing in the source of Backbone.Stickit that requires that the model actually be an instance of Backbone.Model. So, it does appear that Stickit just needs some object that supports the contract provided by Backbone.Model--the various applications of set(), get() and on() are all I think you need.
Take a look at Stickit's test suite. If you wrote your own model API that passed that those tests (by replacing Backbone.Model with your own implementation in testScaffolding.js--and presuming the tests are thorough--then you should be able to use that model with Stickit.
EDIT: I may not have directly addressed the question. Stickit only requires that you use it in a Backbone.View, and that that view has either a model, or some other object specified by the optionalModel parameter you can pass to the stickit() function, that meets the contract provided by Backbone.Model.
My model has a couple properties one is a string and the other is an observablecolletion. When the model is created it fires off a backgroundworker thread to basically poll a .dll for data. Based on the data it receives it will either set the string and/or add and item to observable collection. My string property seems to fire its Onproperty change just fine and the view updates. However, my observable Collection throws a cross thread exception. I have tried moving code where i set the ObesrvableCollection to the worker.ReportProgress and get the same error. I have moved the logic into the view model and still get the same threading error. I'm unsure why my string property works for one. I have read about Dispatcher.Invoke, but i'm pretty sure that my model should not be aware of this. Can anyone explain the correct way to go about this please.
Just fyi - my view is not tied directly to my model. I have a property for my model in my viewModel and the model gets passed through constructor injection. Just want to put that out there before anyone thinks my model is talking directly to the the view.
Hard to give specifics without code. However, WPF automatically marshals property change notifications for scalar properties but not collections. Hence, you must be modifying the collection from a non-UI thread.
There is no reason why your VM can't use Dispatcher, or perhaps the more generic SynchronizationContext if you prefer. It can make things more tricky to test, however.
If you post code there may be a way you can simplify things.
As Kent said, if you're not on the UI you need to use the Dispatcher to update your collection:
Application.Current.Dispatcher.Invoke(new Action(() =>
{
// update your ObservableCollection here
}));
I am writing a fairly large scale WPF desktop application using the MVVM pattern. I have been stuck for a while on getting my common properties to update in a View other than the one that updated it.
I have a RibbonWindow MainView that contains a ContentControl that displays the remaining Views one at a time dependant on the user's selection. I have a BaseViewModel class that all the ViewModels extend. Among other things, this class exposes the INotifyPropertyChanged interface and contains a static property of type CommonDataStore. This class also implements the INotifyPropertyChanged interface and contains the properties that are to be available to every ViewModel.
Now, although I can access and successfully update the CommonDataStore properties from any ViewModel, the problem is that the WPF Framework will only notify properties that have changed in the current View. Therefore, although the common values have been updated in other ViewModels, their associated Views do not get updated.
One example from my application is the login screen: As the user logs in, my LogInView updates with the new information (ie. full name) from the database, but the user details in the MainView do not.
After reading a few other posts, I also tried implementing the CommonDataStore class as a Singleton, but that didn't help. I could also just pass a reference to this common data object to the constructor of each ViewModel from the MainViewModel, but I'm not sure if this is the right way to go.
I have also discovered that in WPF, static properties are treated a bit like constant values. It seems that they just read the value once.
So anyway it's clear, my attempts have all failed. I was wondering what the standard way of doing this was? In particular, I need to be able to bind to the common properties and have all of my ViewModels and Views update when any common value is changed. Any help would be greatly appreciated. Many thanks in advance.
Edit >> Really? No one uses application wide variables in an MVVM WPF application?
I have now removed the static part of the Common property declaration and am simply passing a copy into each ViewModel individually. This seems to work, but I'd really like to know how others approach this situation. Please answer by simply letting me know how you organise this application wide data.
I have done something similar to what you describe last. I have class called SecurityContext that holds some of the application-wide data. One instance is created when the application starts up and then that instance is passed into the constructors of all the ViewModels through dependency-injection. I have a base class for ViewModels which exposes that object through a regular instance property (implementing INotifyPropertyChanged).
Have you looked into implementing the Observer Pattern? We have done so with IObservable and IObserver. This describes the "IObservable/IObserver Development Model" as follows:
The IObservable/IObserver development model provides an alternative to using input and output adapters as the producer and consumer of event sources and sinks. This model is based on the IObservable/IObserver design pattern in which an observer is any object that wishes to be notified when the state of another object changes, and an observable is any object whose state may be of interest, and in whom another object may register an interest. For example, in a publication-subscription application, the observable is the publisher, and the observer is the subscriber object. For more information, see Exploring the Observer Design Pattern on MSDN.