At present my project designed with zk MVC pattern where a page looks like
The corresponding Java implementation
SampleFenericFwdComposer extends GenericForwardComposer{
doAfterCompose(Window win){
super.doAfterCompose();
.....
}
onClick$someButton(Event evt){....}
onSelect$sampleListbox(Event evt) {....}
private mehtods
....
}
DAO classes using Hibernate for dataModel which will be rendered for each page
SampleEntity1 implements Serializable{
accessors , mutators
}
Please let me know how to move to MVVM. MVVM pattern says use ViewModel pojo to bind with page. If so is tat my "SampleEntity1" class should be used as 'ViewModel' ?
If so , it not a good pattern as far im concerned....
it's wide question. I think SampleEntity1 is a Model rather then ViewModel. You should create a new ViewModel which would have reference to Model.
Interpreting your code I would say that:
SampleFenericFwdComposer - should be a View - SampleFenericFwdComposerView
SampleFenericFwdComposerViewModel - should be pass to View by DataContext,
SampleEntity1 - should be a Model and ViewModel should reference to it only.
Related
I want to call a service interface in the ViewModel constructor without using any libraries for MVVVM like MVVMLight etc like
public HomePageViewModel(IHomeService homeService)
{
}
This is how we do it using a MVVM light.
IService _tService;
public HomePageViewModel(IHomeService homeService, INavigationServiceExtended navigationService, IService tService)
{
_tService=tService;
}
How can I get the send the IHomeService instance from the view while binding the View to the ViewModel .
When using DI you either inject the dependency in the calling code, in your case you do something like this:
var homePageViewMdel = new HomePageViewModel(new HomeServiceImplementation());
Or either you would use an IoC container like (Unity, DryIoc or Autofac) or write your own IoC from scratch.
I have some doubts about what are the best practices for MVVM using parent-child model relations.
In that specific case there are two models (data classes) called Group and Contact. The group is containing a list of contacts. Both of them are are implementing INotifyPropertyChanged interface.
In the view, there is a treeview displaying the hierarchy using DataTemplate and the associated ViewModel contains an ObservableCollections property.
I am wondering what is the best practice design in this case.... Having one property like above in the ViewModel which is bind to the xaml or createing a ViewModel for each model (like GroupViewModel and ContactViewModel) and instead of ObservableCollections having an List.
What is the best way (design wise)? Shoudl I bind the Model or the ViewModel to the xaml?
I'm afraid, you mixed some things up. The basics of MVVM are
Model - Contains the data the application is working with. It should be kept as simple as possible.
ViewModel - Reflects the state of the application and contains the business logic. It's the business layer.
View - Interprets the ViewModel to provide a visual representation of the business layer and its state.
With this three parts, it's pretty easy to provide separation of concerns and a decoupled architecture. If you want to read more, click here.
Back to your questions:
In that specific case there are two models (data classes) called Group and Contact. The group is containing a list of contacts. Both of them are are implementing INotifyPropertyChanged interface.
That's a bit odd. Usually, you don't need to implement INotifyPropertyChanged in the model classes, since the VM should handle value changes from the view.
But it's imaginable to have that mechanism in the model layer too. But since you don't want to track changes on this layer and IMHO the VM should take care about, you don't need it.
[...] Having one property like above in the ViewModel which is bind to the xaml or createing a ViewModel for each model (like GroupViewModel and ContactViewModel) [...]
Yes, this is usually the approach. For each model class, which should be passed to the view layer, you would create a ViewModel.
[...] and instead of ObservableCollections having an List.
That's definitely a No. If you use a List<T>, the view would not be aware of the changes (add, remove) to collection.
What is the best way (design wise)? Shoudl I bind the Model or the ViewModel to the xaml?
Simply stick to MVVM. The view is aware of the VM, but the VM is not aware of the view. Additionally the VM is aware of the model, but the model isn't aware of it. That implies, that you should always bind the VM to the View.
Edit
The following is totally legit.
public class Address : ViewModelBase // implements INotifiedPropertyChanged a.s.o.
{
public string Street { /* you know what comes here */ }
public string ZipCode { /* ... */ }
public string City { /* ... */ }
/* more properties */
}
public class Person : ViewModelBase
{
public string Name { /* ... */ }
public Address Address { /* ... */ }
}
I started working with the MVVM pattern in a new project.
Everything is ok, but i came to the following problem.
The implementation looks like this:
I have a MainView, the main app window. In this window i have a telerik RadGroupPanel in wich I host the rest of the app views as tabs.
The rest of the viewModels does not know about this RadGroupPanel which is hosted in MainVIew.
How should i correctly add those views to the RadGroupPanel from the commands in the viewModels?
Thanks.
Have you considered injecting your view into the ViewModel using an interface to maintain separation? I know this breaks MVVM but I've successfully used this on a number of WPF projects. I call it MiVVM or Model Interface-to-View ViewModel.
The pattern is simple. Your Usercontrol should have an interface, call it IView. Then in the ViewModel you have a property with a setter of type IMyView, say
public IMyView InjectedView { set { _injectedView = value; } }
Then in the view you create a dependency property called This
public MyUserControl : IMyView
{
public static readonly DependencyProperty ThisProperty =
DependencyProperty.Register("This", typeof(IMyView), typeof(MyUserControl));
public MyUserControl()
{
SetValue(ThisProperty, this);
}
public IMyView This { get { return GetValue(ThisProperty); } set { /* do nothing */ } }
}
finally in Xaml you can inject the view directly into the ViewModel using binding
<MyUserControl This="{Binding InjectedView, Mode=OneWayToSource}"/>
Try it out! I've used this pattern many times and you get an interface to the view injected once on startup. This means you maintain separation (Viewmodel can be tested as IView can be mocked), yet you get around the lack of binding support in many third party controls. Plus, its fast. Did you know binding uses reflection?
There's a demo project showcasing this pattern on the blog link above. I'd advocate trying out the Attached Property implementation of MiVVM if you are using a third party control.
You can have the list of viewmodels that you need to add controls for in an ObservableCollection in your main window viewmodel. You can then bind the ItemsSource of the RadGroupPanel to that collection and use the ItemTemplateSelector and ContentTemplateSelector of the RadGroupPanel to select the right template to use based on the viewmodel that is bound.
in my ASP MVC 2 application I follow the strongly typed view pattern with specific viewmodels.
Im my application viewmodels are responsible for converting between models and viewmodels. My viewmodels I have a static ToViewModel(...) function which creates a new viewmodel for the corresponding model. So far I'm fine with that.
When want I edit a model, I send the created viewmodel over the wire and apply the changes to back to the model. For this purpose I use a static ToModel(...) method (also declared in the view model). Here the stubs for clarification:
public class UserViewModel
{
...
public static void ToViewModel(User user, UserViewModel userViewModel)
{
...
}
public static void toModel(User user, UserViewModel userViewModel)
{
???
}
}
So, now my "Problem":
Some models are complex (more than just strings, ints,...). So persistence logic has to be put somewhere.(With persistence logic I mean the decisions wheater to create a new DB entry or not,... not just rough CRUD - I use repositories for that)
I don't think it's a good idea to put it in my repositories, as repositories (in my understanding) should not be concerned with something that comes from the view.I thought about putting it in the ToModel(...) method but I'm not sure if thats the right approach.
Can you give me a hint?
Lg
warappa
Warappa - we use both a repository pattern and viewmodels as well.
However, we have two additonal layers:
service
task
The service layer deals with stuff like persisting relational data (complex object models) etc. The task layer deals with fancy linq correlations of the data and any extra manipulation that's required in order to present the correct data to the viewmodel.
Outwith the scope of this, we also have a 'filters' class per entity. This allows us to target extension methods per class where required.
simples... :)
In our MVC projects we have a seperate location for Converters.
We have two types of converter, an IConverter and an ITwoWayConverter (a bit more too it than that but I'm keeping it simple).
The ITwoWayConverter contains two primary methods ConvertTo and ConvertFrom which contain the logic for converting a model to a view model and visa versa.
This way you can create specific converts for switching between types such as:
public class ProductToProductViewModelConverter : ITwoWayConverter<Product,ProductViewModel>
We then inject the relevant converters into our controller as needed.
This means that your conversion from one type to another is not limited by a single converter (stored inside the model or wherever).
I have created a UserSiteBaseController that gets commonly used data and sets the data to a UserSiteBaseViewData viewmodel in a method called SetViewData
public T CreateViewData<T>() where T : UserSiteBaseViewData, new()
{
....
}
I then create specific Controllers that inherit from the UserSiteBaseController as well as viewModels that inherit from UserSiteHomeViewData and can be created in the controller like so:
public ActionResult Index(string slug)
{
Slug = slug;
var viewData = CreateUserSiteHomeViewData<UserSiteHomeViewData>();
//If invalid slug - throw 404 not found
if (viewData == null)
return PageNotFound();
viewData.Announcements = _announcementsData.All(slug).ToList();
return View(viewData);
}
private T CreateUserSiteHomeViewData<T>() where T : UserSiteHomeViewData, new()
{
T viewData = CreateViewData<T>();
return viewData;
}
The UserBaseViewData holds data that needs to be use on every page so it would be great to be able to access this data from the Masterpage in a strongly typed manner. Is this possible or am I going about this in the incorrect manner?
If you get your masterpage to inherit from System.Web.Mvc.ViewMasterPage<BaseViewModel> you should be good to go...?
BUT, when I first started using MVC I went down the same route using a BaseViewModel class which contained all my generic ViewModel stuff and then I created specific view models, e.g. EventListingViewModel, which inherited from this BaseViewModel - much like you are doing. My masterpages then inherited from System.Web.Mvc.ViewMasterPage<BaseViewModel> and everything was going swell.
But after a while it all became a bit tightly coupled and a quite brittle. It became a pain in the ass to make changes and what not. I also came across this issue.
So I've reverted back to using the standard ViewData dictionary (with a static VewDataKeys class to avoid magic strings) for all my generic properties and then using custom POCO objects that don't inherit from anything as my presentation models. This is working much better and I wouldn't change back.
HTHs,
Charles