Closed. This question is opinion-based. It is not currently accepting answers.
Want to improve this question? Update the question so it can be answered with facts and citations by editing this post.
Closed 8 years ago.
Improve this question
I have just started to develop in universal app. I have developed app in Windows 8 store apps and also developing Windows Phone 8 and Windows Phone 8.1 (SilverLight) Apps. Question is related to universal app in Windows and Single UI which is created in App. Share folder.
1. I am new in MVVM. I have developed Windows phone 8 and WP8.1 app in normal way. But not with MVVM. I have search a lot but did not get any example which can make better understand of MVVM. I know what is MVVM. It is similarly of MVC of Asp.net.
MVVM is
Model : Which describe data
View-Model : In simple word a bridge between Model and View.
View : A simple xaml page or user interface.
Which way is better or best to do code in Windows Phone 8 MVVM or Normal way?
Normal way means without using MVVM.
Ref : Separate UI and app logic using the Model-View-ViewModel pattern
This is a broad question to answer in a single post. I'll provide a couple of things to think about and research.
(Note: all code in this post is free hand from memory. It may not be 100% syntactically correct.)
You are for the most part correct in your definition of MVVM. The main difference to me between MVVM and MVC is that binding is used to connect the View to the View Model (Controller). That is semantics though and don't need to get hung up on it.
It doesn't matter if you are WP 7, WP 8, WP8.1, Siverlight or Universal App. It may be easiest to start with WPF as that is when MVVM was introduced and it is faster to run your app as it doesn't run in an emulator.
First is to get started with a very basic example.
1) Create folders "Views" and "ViewModels". Strictly not necessary but you will want them.
2) Create a blank page with a TextBlock. This is the xaml file with the code behind. Create it in the Views folder and name it MyFirstPage. Put a text block on it like this:
<TextBlock Text="The Title of my App" />
3) Run the app and make sure this text is showing.
4) Create a ViewModel class. This is a basic class file. Create it in the ViewModels folder and name it MyFirstViewModel.
5) Connect Page(View) to ViewModel. Here is what my code behinds look like and for the most part this is all I have in them. Setting the DataContext to the view model is the key to setting up the binding. There are many other frameworks out there that make this magic, but this is what happens. This is the best place to start in my opinion.
public class MyFirstPage : Page
{
private MyFirstViewModel _viewModel = new MyFirstViewModel();
public MyFirstPage()
{
this.Initialize???
this.DataContext = _viewModel;
}
6) Add a Title Property to your View Model and for now just have it return a hard coded value.
public string Title { get { return "The Title of my App (set from View Model)"; } }
7) Update TextBlock on View to use Binding
<TextBlock Text="{Binding Title}" />
8) Run the app to test that it works.
So that is the basics to hook up a view model to a view and see the binding work.
Next up to learn:
Two Way Binding: If you have values being set on the UI in TextBox you will need to update the binding to look like {Binding FirstName, Mode=TwoWay} as an example if you want to enter a first name.
Observable Properties: Another problem you will find is that when you view model logic changes the values of the bound properties the values won't display on the UI. You will pull your hair out wondering what is wrong but it is really simple. The UI needs to be notified to update. You changed the underlying value but the UI has no idea to update. So for properties like FirstName you will need to implement INotifyPropertyChanged on your ViewModel and in the setter of your property call OnPropertyChanged("FirstName"). There are lots of examples out there that describe this.
ObservableCollections: Similar to Observable Properties if you have a list of items that get adjusted in the view model, the view will need to be notified that the list has changed. The way to do this is to make the property an ObservableCollection. Again, lots of examples. The tip I have is only implement a getter for these properties. You want to either create the collection once in the constructor or lazy load in the getter of the property. If you ever create a new instance of the ObservableCollection the link to the UI will get broke and you will have to call OnPropertyChanged for this which really is not necessary if you just use a single instance of ObservableCollection and and and removed items from it. You'll see what I mean after playing with it a bit. Just re-read this again.
Converters: Now we are moving to the next level but to keep your code behind clean you will leverage converters and relay commands. A most common converter is BooleanToVisibilityConverter. This will help control the Visibility of a view component based on a boolean value on your View Model. Again, you will have to research this.
Relay Commands: Like converters you need Relay Commands to keep your code behind clean. A relay command is basically a binding for a click event. Instead of having a click event handler in the code behind you will have a Relay Command implemented in your ViewModel and for instance a Button Command will bind to the RelayCommand property on your View Model.
Once you research and are familiar with these items you will be off to a good start.
It is really hard in some cases to avoid the code behind, but what I have found is that I have been able to find solutions for most problems, however, it sometimes requires creativity.
Once last comment:
My goal in creating a strict clean ViewModel is so that I can reuse it across form factors (Phone and Tablet). This is possible but is more difficult once you get deep in to harder problems. However, the key here is that you have a separate Lib project for your ViewModels to live in. All my solutions have Windows Phone 8.1 Project, a Windows 8.1 (Store) Project, and a Portable class Lib project. The ViewModels folder goes into the Lib project along will all other code that is shareable. To make everything work you may have to use Inversion of Control but that is a topic for another post.
Good Luck and Have fun,
Tom
Take a look at Nico Vermeir's introduction tutorial on MVVM Light here http://www.spikie.be/blog/post/2014/06/30/.aspx
The answer is too large to post on stackO so follow the url :)
Related
I have been working on a mobile application for one week, for personal education and enhancement. I have some experience with WPF and MVVM, I have no experience with mobile development.
The idea is to make a cross platform application, while testing some coding philosophies :
Reactive programming (ReactiveUI)
Vertical slicing, if possible (blog 1, blog 2)
I plan to use the following components :
Prism.Unity.Forms : seems to provide application structure, ioc, navigation, seems widely used, and done by top notch people
ReactiveUI, ReactiveUI.XamForms, ReactiveUI.Fody : WhenAnyValue, ObservableAsPropertyAttribute, ReactiveAttribute (tutorial), not using them looks like a huge missed opportunity to me
The current structure of my Visual Studio is the following :
Csproj
ViewModels
CreateExercisePageViewModel
HomePageViewModel
Views
CreateExercisePage
HomePage
I managed the following :
Set the HomePage as the initial Page, contained inside a NavigationPage, by using the navigation functionalities of Prism.
Declare a named button in XAML, set its Command property through a OneWay binding created in code behind, using ReactiveUI functionalities (like shown in the tutorial, using the WhenActivated method)
Navigate to the second page (CreateExercisePage), using Prism navigation
One issue is that, even though I have seen a few articles regarding vertical slicing, there were mostly about web applications.
So the question is : Is vertical slicing applicable to mobile applications ?
I would like to restructure my project by using vertical slicing, but having troubles finding articles about Xamarin Forms, I feel uneasy.
Edit : my understanding of the vertical slicing concept, is that you should group code, related to a feature, in the same physical space (folder). By doing so, it gives developers a huge hint about the cohesion of those files.
Given a mobile application is made of screens, I assumed grouping code by screen, regardless of their type (presentation, logic, persistence) would make sense.
Rewriting the application would give the following csproj, then :
Csproj
Screens
Home
HomePage
HomePageViewModel
CreateExercise
CreateExercisePage
CreateExercisePageViewModel
Adding a new screen would mean adding a new folder to the "Screens" folder, reducing the risk of modifying existing files/logic.
Vertical Slicing is a little bit like MVVM which we are utilizing on Xamarin.Forms:
https://learn.microsoft.com/en-us/xamarin/xamarin-forms/enterprise-application-patterns/mvvm
The view is the UI layer, view model helps you handle the logic code and model represents your database data.
For instance, a user clicks the button on view layer to trigger a command in the view model. Then this command could add a new product to the List property of that view model. As this list property has been changed it will notify the UI to respond to this action.
Moreover, your first architecture is more appropriate:
ViewModels
CreateExercisePageViewModel
HomePageViewModel
Views
CreateExercisePage
HomePage
Make your pages separated by your view models.
I recently inherited a Xamarin project where I am to work on the iOS project. Going over several tutorial I figured I was ready, however the person before me did not use storyboards or controllers! They did all customization of views in files named LoginScreens.cs (basically controller files from the looks of it).
For learning purposes and ease of transition I would like to get a storyboard going in this project. So I created a storyboard titled Main and added a ViewController and essential copy and pasted the view customization code used in the LoginScreen.cs into my controller.
To be a little more specific, I have a Main.Storyboard that looks like this:
Where I am using editText boxes and a button to act as place holders for what I actually do to them in the ViewController.cs.
This all seems to register and builds properly however when I run the debugger on iPhone 6s iOS 9.3 I get the following:
The changes appear to show, but all my storyboard iOS designer views remain in place. I am trying to see if there is a way to reflect the changes made in the controller on the storyboard.
TL;DR: I'm trying to alter some views in a programmatic way in my ViewController.cs file. These views were originally added via the iOS designer and for customization purposes, they were edited in the controller. I want to see the visual alteration I make on a view in the controller, reflect in the iOS designer and when I debug.
Sounds like you are trying to go from a project where views were all done programmatically to implementing storyboards. This is a Big change and will take some time to convert the views over.
In the cs file there will be things like Add(passwordTextFeild) which are going to add more views to your storyboard view, hence why you get alot of views in your login view. You wont be able to see these in the storyboard as they are done at runtime.
If you are looking for IBDesignable this is more for custom controls and you still will have to add code to be able to see the changes from the .cs file in the storyboard.
Check my Question for IBInspectable/IBDesignable in Xamarin
Check this official link: https://developer.xamarin.com/guides/ios/user_interface/designer/ios_designable_controls_walkthrough/
Probably not what you wanted to hear but the UI in iOS projects tend to be done in one of the three methods:
All programmatically
Storyboards
Xibs
There are tons of questions/blog posts (even a video), weighting up the pros and cons of each. So possibly the last developer felt it was best to do it programmatically
There is a setting, IBDesignable, that you can add to the declaration of UI classes in Swift or Objective-C. That tells Xcode the those UI objects have a custom interface that you want to be presented in Interface Builder.
I have no idea how (or even if you could) you would use IBDesignable in Xamarin/C#. If its not supported for Xamarin then you're probably out of luck.
I suggest you search on "Xamarin IBDesignable" on the net.
I have a Xamarin Forms project targeting iOS, Android and Window Phone. I am using MVVM for this project. All View Models are in a PCL and the UI is mostly in a shared project, such as ProjectUI. So, I have ProjectLib - the PCL, ProjectUI - the "shared" UI, ProjectUI.Android, ProjectUI.iOS, ProjectUI.Winphone.
Under ProjectLib, I have ProjectData - this defines all data objects that are used on both the client and server.
The app is generally running, but we have to come up with a way to add field level help to the app. To that end, we have added properties to the data that allow the user to define field level help.
If I have a property called FirstName, I would have another property called FirstName_Help. If FirstName_Help is non-blank, I'd like to change the style of the FirstName ("First Name:") prompt to show there is field level help for this field. Then, if the user taps the prompt, we'd like to pop-up a message with help text in it. If the FirstName_Help property is empty string, we do NOT want to change the prompt nor allow tapping on the prompt.
We have chosen this prompt method to reduce screen real-estate needed to depict there is help available, so I'd like to keep to this as our method if at all possible.
Because we are doing this via MVVM, I'd like to keep the code, if at all possible, in the View Model, not code behind. If we have to go with code behind, then we'll do that, but I'd love to keep it MVVM if at all possible.
I believe I can achieve the prompt change via a style, but I'm just not exactly sure how to go about doing it. The other challenge is how do I get the correct help text to display on the tap of the prompt?
I'd love to hear your thoughts on how this can be accomplished.
Thanks in advance.
I have an application which use plugins. Each plugin is developped following MVVM, so I have a View, binded to a View-Model inside. like the following picture:
In my application I have a Designer, when I add any ViewModel in my ViewModels list, its view will appear in the Designer.
My question is: How can I keep this binding when adding the viewModel of my plugin in my list ?? how to make its view appear in my designer ?
This is an interesting question... and like always there are many ways to accomplish it.
It depends what your plugins are.
If the plugin is more integrated and not so isolated. You should think about some Factory classes which are for example named like ViewResolver or ViewModelResolver. They can take parameters like the name as string, a type, a type of an interface or work by conventions.
Purpose is to find the VM for a view and vice versa as a central service. This service should also locate plugin VM or import them for example with MEF.
For more info’s google on view-first, viewmodel-first, view viewmodel marriage, etc.
Or
If your plugins are fully fleshed out components which run independently. I would suggest your host application should have in its viewmodel a list of components which are the plugins. So the Model will be a Component no matter if it contains the view and everything else because of the hosting app is to manage the components. So you would have an ObservableCollection which are bound to content control. The content control can then host the plugin as a whole.
These are two possible ways... like I mentioned above there is no "the" way in mvvm and it always depends on your use cases...
But I hope this guides you in the right direction...
HTH
Thank you for the answer #Silverfighter! it made me things more clear !
I found a very intersting article wich seems adapted to my problem
The solution is here:
http://www.alphablog.org/2012/05/07/simple-plugin-system-based-on-ninject-and-mvvm-light-2/
Can IDataError info be used properly in a winforms application? In the past I was doing my binding the usual way(1) and did the validation in the OnValidating event of the particular control. I would like to move the data validation to the domain model so that I can easily swap out user interfaces and so that all of the logic is in one place.
I was looking into IDataErrorInfo but everything I find deals with WPF and the app in development is strictly a winforms app.
I also noticed that the binding that gets used in WPF is in System.Windows.Data and the binding that I've always been using is in System.Windows.Forms (which I don't appear to have when I try to add it as a resource - I'm using 3.5).Aside from the property "ValidatesOnDataErrors" is there a difference between the two?
(1) the usual way being:
myControl.DataBindings.Add(new Binding("Text", this.domainModel, "Property"));
This works with the ErrorProvider component in Windows Forms.
For a complete, but very simple and short tutorial, see this blog post.
Yes, IDataErrorInfo works in winforms. For example, DataGridView will use this automatically both per-row and per-cell. But it is implementation-specific, and isn't automatically applied to other bindings. I did once write some code to associate it to an error-provider and do the work via change events, but I don't have it to hand unfortunately. But I seem to recall it wasn't huge.