Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Added overview doc explaining MVVM Basic #2210

Merged
merged 2 commits into from
Apr 24, 2018
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
4 changes: 2 additions & 2 deletions docs/getting-started-endusers.md
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ Windows Template Studio approaches UWP app creation using the following four att
| Design pattern| Description |
|--------------:|:------------|
| Code Behind | Code is coupled directly with a XAML file using a .xaml.cs extension. If you developed in WinForms and feel comfortable with that style of development, this is a great option for you. |
| MVVM Basic | A generic implementation of the [Model-View-ViewModel (MVVM) pattern](https://en.wikipedia.org/wiki/Model%E2%80%93view%E2%80%93viewmodel), which can be used on all XAML platforms. Its intent is to provide a clean separation of concerns between the user interface (UI) controls and their logic. |
| MVVM Basic | [MVVM Basic](./mvvmbasic.md) includes the minimum necessary to follow the MVVM pattern without including any extra libraries or dependencies. It is intended for people new to MVVM or who are unable to or do not wish to use a 3rd party framework. |
| MVVMLight | The [MVVM Light Toolkit](http://www.mvvmlight.net/) is a popular, 3rd party toolkit by Laurent Bugnion, which has the purpose of accelerating the creation and development of MVVM applications. This toolkit puts a special emphasis on the "blend ability" of the created application (the ability to open and edit the user interface into Blend), including the creation of design-time data to enable Blend users to "see something" when they work with data controls.<br />As a toolkit, it provides a number of tools and features but there is no requirement to use all of them. This toolkit is popular with developers who want use parts of it to take care of the basics but still allow them to structure the code in their own way. |
| Caliburn.Micro| [Caliburn.Micro](https://caliburnmicro.com/) is a small, yet powerful framework, designed for building applications across all XAML platforms. Its strong support for MV* patterns will enable you to build your solution quickly, without the need to sacrifice code quality or testability.<br />It uses a convention based approach to mapping actions/events, bindings, and views to view models. While this framework is highly opinionated about how it should be used and apps should be constructed, it does allow for customization of it's behavior.<br />WTS only supports the use of Caliburn.Micro with projects created in C#. |
| Prism | [Prism](https://github.com/PrismLibrary/Prism) is a framework for building loosely coupled, maintainable, and testable XAML applications. It was originally based on guidance from Microsoft's Patterns and Practices team but is now supported by an open source community. It is designed to help build rich client applications that are flexible and easy to maintain by composing different modules and following design patterns.<br />WTS only supports the use of Prism with projects created in C#. |
Expand Down Expand Up @@ -79,7 +79,7 @@ Windows Template Studio approaches UWP app creation using the following four att
| Live Tile | Enables modification and updates to your app's presence on the Windows 10 Start Menu, providing the ability to change the app's visual state and provide additional context or information. |
| First Run Prompt | Display a prompt when the app is used for the first time. |
| What's New Prompt | Display a prompt when the app is first used after an update. |
| Feedback Hub Link | Inlcude a link on the settings page that opens the Feedback Hub for your app. |
| Feedback Hub Link | Include a link on the settings page that opens the Feedback Hub for your app. |
| Drag & Drop | A service that simplifies the creation of drag and drop ready apps. |

## Table of Contents
Expand Down
93 changes: 93 additions & 0 deletions docs/mvvmbasic.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,93 @@
# MVVM Basic

MVVM Basic is not a framework but provides the minimum functionality necessary to create an app using the [Model-View-ViewModel (MVVM) pattern](https://en.wikipedia.org/wiki/Model%E2%80%93view%E2%80%93viewmodel). It was created for people who can't or don't want to use a 3rd party MVVM Framework.

MVVM Basic is not intended to be a fully featured MVVM Framework and does not include some features that other frameworks do. ViewModel-first navigation, IOC, and messaging being the most obvious ones. If you want these features we recommend choosing a framework that provides or supports them.
MVVM Basic can also serve as a basis for developers who want to create their own MVVM implementation. By providing only the most basic of extra functionality but still following common conventions it should be the easiest option if you want to modify the generated code to meet your preferred way of working.

## Core files

Projects created with MVVM Basic contain two important classes:

- `Observable`
- `RelayCommand`

`Observable` contains an implementation of the `INotifyPropertyChanged` interface and is used as a base class for all ViewModels. This makes it easy to update bound properties on the View.

`RelayCommand` contains an implementation of the `ICommand` interface to make it easy to have the View call commands on the ViewModel, rather than handle UI events directly. You can see examples of this being used in many of the pages that can be included as part of project generation including Camera, ImageGallery, Settings, and WebView.

## Navigation

MVVM Basic assumes View-based navigation. This means that a ViewModel will trigger navigation to another View. This should be done by calling the `Navigate` method on the `NavigationService` and passing the type of the page you wish to navigate to.

```csharp
NavigationService.Navigate(typeof(SettingsPage));
```

Additionally, you can pass an optional object to the page by including it as the second parameter for the method.

```csharp
NavigationService.Navigate(typeof(DetailsPage), selectedItemId);
```

When passing values this way, they can be accessed in the `OnNavigatedTo` event of the target page. Ths can be seen in the sample below which is from the ImageGallery page.

```csharp
protected override async void OnNavigatedTo(NavigationEventArgs e)
{
base.OnNavigatedTo(e);
await ViewModel.InitializeAsync(e.Parameter as SampleImage, e.NavigationMode);
showFlipView.Begin();
}
```

You can learn more about Navigation within a project [here](./navigation.md).

## ViewModel persistence and lifetime

ViewModels included in the generated pages have a lifetime that is tied to the lifetime of the page that created it.

If you need to reuse a ViewModel in multiple pages, have the ViewModel remain after navigating back from the page, or have multiple instances of a page use the same ViewModel, this can be achieved by

- Making the ViewModel a singleton or other static class.
- Making the ViewModel a property of the app.

### A singleton ViewModel

The [singleton pattern](https://en.wikipedia.org/wiki/Singleton_pattern) ensures that there will only ever be a single instance of a specific type. The generated code includes a helper class for working with singletons.

If you want ViewModel to be treated as a Singleton, access it like this:

```csharp
// C#
this.DataContext = Helpers.Singleton<MainViewModel>.Instance;
```
```vb
' VB.net
this.DataContext = Helpers.Singleton(Of MainViewModel).Instance
```

### App level ViewModels

If you want to access a ViewModel from a number of different places with an app, making it a property of the `App` class is an easy way to achieve this.

```csharp
public sealed partial class App : Application
{
...

// Create an instance when the app launches
public SettingsViewModel Settings => new SettingsViewModel();

...
}
```

Then use it anywhere in the app like this.

```csharp
if ((App.Current as App).Settings.IsLoggingEnabled)
{
...
}
```