Windows 10 UWP MVVM In Depth Brian Noyes CTO & Co-founder, Solliance Inc (www.solliance.net) brian.noyes@solliance.net, @briannoyes
Visual Studio Connections About Brian Noyes CTO and Co-founder, Solliance www.solliance.net Microsoft Regional Director Microsoft MVP Pluralsight author www.pluralsight.com Web API Insider, Windows Azure Insider, Window Store App Insider, C#/VB Insider t e brian.noyes@solliance.net @briannoyes http://briannoyes.net Updates will be available at http://www.devconnections.com/updates/LasVegas_Fall08/VS
Agenda Windows 10 UWP Big Picture MVVM Pattern Fundamentals MVVM Construction Approaches MVVM Communications Integrating MVVM with Windows 10 UWP Platform Features Leveraging MVVM Frameworks
Windows 10 Universal Windows Platform Native APIs of Windows 10 Core APIs common across all Windows 10 platforms Device-Family extensions for desktop, mobile, IoT Derivative from Windows 8 “Windows Runtime” Less prescriptive/constraining than Windows Runtime was Styling Windowing Background tasks App activation
Windows 10 UWP MVVM Not “baked” into the platform at all Same core capabilities exist to use MVVM in UWP XAML apps as other XAML platforms: DataContext Rich two way data binding Property change notifications DataTemplates
Windows 10 UWP MVVM Need to be able to leverage platform specific capabilities and limitations when using MVVM in UWP Frame-based navigation App activation / lifecycle schemes Transient state management Compiled bindings Lack of Implicit DataTemplates
UI Separation Patterns Goals Architectural goals Loose coupling Separation of concerns Leads to Maintainability Testability Extensibility Putting all your logic here is not good enough
No Separation of Concerns private void ComputeCustomerOrdersTotal(object sender, RoutedEventArgs e) { var selectedCustomer = this.customerDataGrid.SelectedItem as Customer; var orders = (from order in dbContext.Orders.Include("OrderItems") where order.CustomerId == selectedCustomer.Id select order); var sum = 0; foreach (var order in orders) { foreach (var item in order.OrderItems) { sum += item.UnitPrice * item.Quantity; } } this.customerOrderTotal.Text = sum.ToString(); } UI Element Access Data Access Interaction/Business Logic
Good Separation of Concerns Business Logic Data Access Model Entities Shared Client Logic View Interaction Logic UI Element Access
MVVM Responsibilities View Data Binding ViewModel Model Model Object Model Object Model Object Client Services / Repositories
Model Responsibilities Contain the client data Expose relationships between model objects Computed properties Raise change notifications INotifyPropertyChanged.PropertyChanged Validation INotifyDataErrorInfo/IDataErrorInfo
View Responsibilities Structural definition of what the user sees on the screen GOAL: “No Code Behind” Reality: Sometimes need some code behind
ViewModel Responsibilities Expose data to the view for presentation and manipulation Encapsulate interaction logic Calls to business/data layer/service Navigation logic State transformation logic
ViewModel Data Model ViewModel OrderItem Customer “Expose” public Customer Customer { get; set; } 1 * public bool ShowCustomerAlert { get; set; } Order “Wrapped” public ObservableCollection<OrderItem> Orders { get; set; } 1 * Client State public bool LoggedIn { get; set; } Order_Detail * 1 OrderItem Product OrderDate Quantity ProductName Authentication Service
Client Services / Repositories Shared functionality or data access Consumed by one or more ViewModels Decouples ViewModels from external dependencies Data storage Service access Client environment Can act as data caching container
MVVM Construction / “Marrying” Schemes Fundamental equation of MVVM: View.DataContext = ViewModel] Approaches: View-First XAML construction View-First Code behind construction View-First ViewModelLocator construction ViewModel-First DataTemplate construction
View-First - XAML InitializeComponent() <UserControl x:Class="ZzaDashboard.Customers.CustomerEditView“ Width="400“ Loaded="OnLoaded" ...> <UserControl.DataContext> <local:CustomerEditViewModel /> </UserControl.DataContext> ... </UserControl>
View-First Code-Behind public partial class CustomerListView : UserControl { public CustomerListView() this.DataContext = new CustomerListViewModel(); InitializeComponent(); }
View-First - ViewModelLocator ViewModelLocator is a meta- pattern for automatically locating and hooking up the right ViewModel
ViewModelLocator Process What view is being constructed? What ViewModel should I construct? Construct (and DI) ViewModel Set ViewModel as View DataContext
Data Binding DataContext <UserControl x:Class="..." ...> <Grid> ... <Label Content="First Name:" ... /> <TextBox ... Text="{Binding Customer.FirstName}"/> <Label Content="Last Name:" ... /> <TextBox ... Text="{Binding Customer.LastName}" /> <Button ... Command="{Binding SaveCommand}" /> </Grid> </UserControl> public class CustomerEditViewModel : INotifyPropertyChanged { public Customer Customer ... } public ICommand SaveCommand { get; set; }
ViewModel-First with Implicit DataTemplates CustomersOrderTreeViewModel <ContentControl Content="{Binding CurrentViewModel}" /> <DataTemplate DataType="{x:Type local:CustomersOrderTreeViewModel}"> <local:CustomersOrderTreeView /> </DataTemplate>
MVVM Communications ViewModel => View : Data binding + property change notifications View => ViewModel : Commands ViewModel = > ViewModel : Pub/Sub messaging
Commands Based on classic Command design pattern Invoker – View control Receiver - ViewModel Use delegating command implementation Supports decoupled command handling invocation Supports enabling/disabling associated control Invoker ICommand Delegate Command Receiver
Hierarchical MVVM / Navigation Page Root View Root ViewModel List View Details View Item ViewModel Item View Item ViewModel Item View List ViewModel Details ViewModel
MVVM and UWP Navigation Page Page ViewModel ViewModel INavigationService FrameNavigationService Frame
Application Lifecycle Management UWP application lifecycle states: Not Running Running Suspended ClosedByUser Terminated Not Running Launch Running Launch Launch Switch Back Switch Apps Terminated Suspended ClosedByUser Low Memory Shutdown
UWP MVVM Frameworks Prism 6 Template10 MVVM Light Caliburn MVVMCross
Prism 6 for UWP Contents Prism.Core Prism.Windows MVVM Support Commands PubSubEvents Prism.Windows Navigation Application State management Validation
Please use Event Board to fill out a session evaluation. Questions? Please use Event Board to fill out a session evaluation. Thank you!