Skip to content

Commit

Permalink
Main > Live (#3234)
Browse files Browse the repository at this point in the history
* Add smart app control docs

* Update two broken links

* Update testing doc with information about audit policies

* Add smart app control docs

* Update in-page link to match updated bookmark

* Update aka.ms link to the audit policies

* Fix typo

* Updates and additional information for the Smart App Control docs

* Adding first files to wasdk data binding topics

* Fix links

* Add start of remaining data binding topics

* Update data binding in depth

* Added section on updating existing apps in the Store

* fix toc.yml issue

* Fill in data binding in depth and func bindings

* Update MVVM binding topic

* Update master details binding topic

* Update xaml in master details topic

* Tweak xaml formatting

* Tweak formatting in master details topic

* Formatting tweaks and remove VB generics syntax

* Modifying incorrect content

* Removing existing update page

* fixing redirection URL

* modified note section in MSIX

* Add function binding topic link to index.

* Additional registry commands to configure SAC, grammar, more notes and clarifications

* remove parameter from a link, and make a different absolute link relative

* WinAppSDK 1.2.2 Release Notes (#3182)

* WinAppSDK 1.2.2 Release Notes

* Typo

* Fixing build warning

* Updated to latest build version

* Grammar fix

Co-authored-by: Steven White <31261191+stevewhims@users.noreply.github.com>

* Update intro for data binding in depth

* Move note before links to APIs

* metadata in master details

Build validation on triggered on last push. Trying a tweak.

* New arm32 to arm64 port doc (#3175)

* New arm32 to arm64 port doc

* Update Arm32 guidance based on word draft

* Update toc wording

* Update guidance to include check and proper terms

* More term updates

* Title update

* Add code tags to appname (#3233)

Co-authored-by: Shawn Hickey <hickeys@microsoft.com>
Co-authored-by: Alvin Ashcraft <aashcraft@microsoft.com>
Co-authored-by: Ankur Singanjude <110964812+AnkurSinganjude@users.noreply.github.com>
Co-authored-by: Gabby Bilka <gabilka@microsoft.com>
Co-authored-by: Steven White <31261191+stevewhims@users.noreply.github.com>
Co-authored-by: QuinnRadich <quradic@microsoft.com>
Co-authored-by: Stacyrch140 <102548089+Stacyrch140@users.noreply.github.com>
Co-authored-by: Paula Miller <v-paulmi@microsoft.com>
Co-authored-by: Alvin Ashcraft <73072+alvinashcraft@users.noreply.github.com>
  • Loading branch information
10 people authored Dec 15, 2022
1 parent 7c0afc8 commit deee97e
Show file tree
Hide file tree
Showing 28 changed files with 1,766 additions and 20 deletions.
5 changes: 5 additions & 0 deletions .openpublishing.redirection.json
Original file line number Diff line number Diff line change
Expand Up @@ -7564,6 +7564,11 @@
"source_path": "uwp/publish/index.md",
"redirect_url": "/windows/apps/publish/",
"redirect_document_id": false
},
{
"source_path": "hub/apps/publish/update-your-app.md",
"redirect_url": "/windows/apps/publish/publish-your-app/publish-update-to-your-app-on-store?pivots=store-installer-msi-exe",
"redirect_document_id": false
}
]
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,209 @@
---
ms.assetid: 6c563dd4-3dd0-4175-a1ab-7a1103fc9559
title: Bind hierarchical data and create a master/details view
description: You can make a multi-level master/details (also known as list-details) view of hierarchical data by binding items controls to CollectionViewSource instances that are bound together in a chain.
ms.date: 12/13/2022
ms.topic: article
keywords: windows 10, windows 11, winui, windows app sdk, windows ui, xBind
ms.localizationpriority: medium
---

# Bind hierarchical data and create a master/details view

> [!NOTE]
> Also see the [Master/detail UWP sample](https://github.com/Microsoft/Windows-universal-samples/tree/master/Samples/XamlMasterDetail).
You can make a multi-level master/details (also known as list-details) view of hierarchical data by binding items controls to [**CollectionViewSource**](/windows/windows-app-sdk/api/winrt/microsoft.ui.xaml.data.collectionviewsource) instances that are bound together in a chain. In this topic we use the [{x:Bind} markup extension](/windows/uwp/xaml-platform/x-bind-markup-extension) where possible, and the more flexible (but less performant) [{Binding} markup extension](/windows/uwp/xaml-platform/binding-markup-extension) where necessary.

One common structure for Windows App SDK apps is to navigate to different details pages when a user makes a selection in a master list. This is useful when you want to provide a rich visual representation of each item at every level in a hierarchy. Another option is to display multiple levels of data on a single page. This is useful when you want to display a few simple lists that let the user quickly drill down to an item of interest. This topic describes how to implement this interaction. The [**CollectionViewSource**](/windows/windows-app-sdk/api/winrt/microsoft.ui.xaml.data.collectionviewsource) instances keep track of the current selection at each hierarchical level.

We'll create a view of a sports team hierarchy that is organized into lists for leagues, divisions, and teams, and includes a team details view. When you select an item from any list, the subsequent views update automatically.

![master/details view of a sports hierarchy](images/xaml-masterdetails.png)

## Prerequisites

This topic assumes that you know how to create a basic Windows App SDK app. For instructions on creating your first Windows App SDK app, see [Create your first WinUI 3 (Windows App SDK) project](/windows/apps/winui/winui3/create-your-first-winui3-app).

## Create the project

Create a new **Blank App, Packaged (WinUI 3 in Desktop)** project. Name it "MasterDetailsBinding".

## Create the data model

Add a new class to your project, name it **ViewModel.cs**, and add this code to it. This will be your binding source class.

```cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace MasterDetailsBinding
{
public class Team
{
public string Name { get; set; }
public int Wins { get; set; }
public int Losses { get; set; }
}

public class Division
{
public string Name { get; set; }
public IEnumerable<Team> Teams { get; set; }
}

public class League
{
public string Name { get; set; }
public IEnumerable<Division> Divisions { get; set; }
}

public class LeagueList : List<League>
{
public LeagueList()
{
AddRange(GetLeague().ToList());
}

public IEnumerable<League> GetLeague()
{
return from x in Enumerable.Range(1, 2)
select new League
{
Name = "League " + x,
Divisions = GetDivisions(x).ToList()
};
}

public IEnumerable<Division> GetDivisions(int x)
{
return from y in Enumerable.Range(1, 3)
select new Division
{
Name = String.Format("Division {0}-{1}", x, y),
Teams = GetTeams(x, y).ToList()
};
}

public IEnumerable<Team> GetTeams(int x, int y)
{
return from z in Enumerable.Range(1, 4)
select new Team
{
Name = String.Format("Team {0}-{1}-{2}", x, y, z),
Wins = 25 - (x * y * z),
Losses = x * y * z
};
}
}
}
```

## Create the view

Next, expose the binding source class from the class that represents your page of markup. We do that by adding a property of type `LeagueList` to **MainWindow**.

```cs
namespace MasterDetailsBinding
{
public sealed partial class MainWindow : Window
{
public MainWindow()
{
this.InitializeComponent();
ViewModel = new LeagueList();
}
public LeagueList ViewModel { get; set; }
}
}
```

Finally, replace the contents of the **MainWindow.xaml** file with the following markup, which declares three [**CollectionViewSource**](/windows/windows-app-sdk/api/winrt/microsoft.ui.xaml.data.collectionviewsource) instances and binds them together in a chain. The subsequent controls can then bind to the appropriate `CollectionViewSource`, depending on its level in the hierarchy.

``` xaml
<Window
x:Class="MasterDetailsBinding.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="using:MasterDetailsBinding"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
mc:Ignorable="d">

<Window.Resources>
<CollectionViewSource x:Name="Leagues"
Source="{x:Bind ViewModel}"/>
<CollectionViewSource x:Name="Divisions"
Source="{Binding Divisions, Source={StaticResource Leagues}}"/>
<CollectionViewSource x:Name="Teams"
Source="{Binding Teams, Source={StaticResource Divisions}}"/>

<Style TargetType="TextBlock">
<Setter Property="FontSize" Value="15"/>
<Setter Property="FontWeight" Value="Bold"/>
</Style>
<Style TargetType="ListBox">
<Setter Property="FontSize" Value="15"/>
</Style>
<Style TargetType="ContentControl">
<Setter Property="FontSize" Value="15"/>
</Style>
</Window.Resources>

<Grid>
<StackPanel Orientation="Horizontal">

<!-- All Leagues view -->
<StackPanel Margin="5">
<TextBlock Text="All Leagues"/>
<ListBox ItemsSource="{Binding Source={StaticResource Leagues}}"
DisplayMemberPath="Name"/>
</StackPanel>

<!-- League/Divisions view -->
<StackPanel Margin="5">
<TextBlock Text="{Binding Name, Source={StaticResource Leagues}}"/>
<ListBox ItemsSource="{Binding Source={StaticResource Divisions}}"
DisplayMemberPath="Name"/>
</StackPanel>

<!-- Division/Teams view -->
<StackPanel Margin="5">
<TextBlock Text="{Binding Name, Source={StaticResource Divisions}}"/>
<ListBox ItemsSource="{Binding Source={StaticResource Teams}}"
DisplayMemberPath="Name"/>
</StackPanel>

<!-- Team view -->
<ContentControl Content="{Binding Source={StaticResource Teams}}">
<ContentControl.ContentTemplate>
<DataTemplate>
<StackPanel Margin="5">
<TextBlock Text="{Binding Name}"
FontSize="15" FontWeight="Bold"/>
<StackPanel Orientation="Horizontal" Margin="10,10">
<TextBlock Text="Wins:" Margin="0,0,5,0"/>
<TextBlock Text="{Binding Wins}"/>
</StackPanel>
<StackPanel Orientation="Horizontal" Margin="10,0">
<TextBlock Text="Losses:" Margin="0,0,5,0"/>
<TextBlock Text="{Binding Losses}"/>
</StackPanel>
</StackPanel>
</DataTemplate>
</ContentControl.ContentTemplate>
</ContentControl>
</StackPanel>
</Grid>
</Window>
```

Note that by binding directly to the [**CollectionViewSource**](/windows/windows-app-sdk/api/winrt/microsoft.ui.xaml.data.collectionviewsource), you're implying that you want to bind to the current item in bindings where the path cannot be found on the collection itself. There's no need to specify the `CurrentItem` property as the path for the binding, although you can do that if there's any ambiguity. For example, the [**ContentControl**](/windows/windows-app-sdk/api/winrt/microsoft.ui.xaml.controls.contentcontrol) representing the team view has its [**Content**](/windows/windows-app-sdk/api/winrt/microsoft.ui.xaml.controls.contentcontrol.content) property bound to the `Teams` `CollectionViewSource`. However, the controls in the [**DataTemplate**](/windows/windows-app-sdk/api/winrt/microsoft.ui.xaml.datatemplate) bind to properties of the `Team` class because the `CollectionViewSource` automatically supplies the currently selected team from the teams list when necessary.

## See also

- [Data binding overview](data-binding-overview.md)
- [Data binding in depth](data-binding-in-depth.md)
58 changes: 58 additions & 0 deletions hub/apps/develop/data-binding/data-binding-and-mvvm.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
---
ms.assetid: b7a8ec88-3013-4e5a-a110-fab3f20ee4bf
title: Data binding and MVVM
description: Data binding is at the core of the Model-View-ViewModel (MVVM) UI architectural design pattern, and enables loose coupling between UI and non-UI code.
ms.date: 12/13/2022
ms.topic: article
keywords: windows 10, windows 11, windows app sdk, winui, windows ui, mvvm
ms.localizationpriority: medium
---

# Data binding and MVVM

Model-View-ViewModel (MVVM) is a UI architectural design pattern for decoupling UI and non-UI code. With MVVM, you define your UI declaratively in XAML and use data binding markup to link it to other layers containing data and commands. The data binding infrastructure provides a loose coupling that keeps the UI and the linked data synchronized and routes user input to the appropriate commands.

Because it provides loose coupling, the use of data binding reduces hard dependencies between different kinds of code. This makes it easier to change individual code units (methods, classes, controls, etc.) without causing unintended side effects in other units. This decoupling is an example of the *separation of concerns*, which is an important concept in many design patterns.

## Benefits of MVVM

Decoupling your code has many benefits, including:

* Enabling an iterative, exploratory coding style. Change that is isolated is less risky and easier to experiment with.
* Simplifying unit testing. Code units that are isolated from one another can be tested individually and outside of production environments.
* Supporting team collaboration. Decoupled code that adheres to well-designed interfaces can be developed by separate individuals or teams, and integrated later.
* Improving maintainability. Fixing bugs in decoupled code is less likely to cause regressions in other code.

In contrast with MVVM, an app with a more conventional "code-behind" structure typically uses data binding for display-only data, and responds to user input by directly handling events exposed by controls. The event handlers are implemented in code-behind files (such as MainWindow.xaml.cs), and are often tightly coupled to the controls, typically containing code that manipulates the UI directly. This makes it difficult or impossible to replace a control without having to update the event handling code. With this architecture, code-behind files often accumulate code that isn't directly related to the UI, such as database-access code, which ends up being duplicated and modified for use with other windows.

## App layers

When using the MVVM pattern, an app is divided into the following layers:

* The **model** layer defines the types that represent your business data. This includes everything required to model the core app domain, and often includes core app logic. This layer is completely independent of the view and view-model layers, and often resides partially in the cloud. Given a fully implemented model layer, you can create multiple different client apps if you so choose, such as Windows App SDK and web apps that work with the same underlying data.
* The **view** layer defines the UI using XAML markup. The markup includes data binding expressions (such as [x:Bind](/windows/uwp/xaml-platform/x-bind-markup-extension)) that define the connection between specific UI components and various view-model and model members. Code-behind files are sometimes used as part of the view layer to contain additional code needed to customize or manipulate the UI, or to extract data from event handler arguments before calling a view-model method that performs the work.
* The **view-model** layer provides data binding targets for the view. In many cases, the view-model exposes the model directly, or provides members that wrap specific model members. The view-model can also define members for keeping track of data that is relevant to the UI but not to the model, such as the display order of a list of items. The view-model also serves as an integration point with other services such as data access code. For simple projects, you might not need a separate model layer, but only a view-model that encapsulates all the data you need.

## Basic and advanced MVVM

As with any design pattern, there is more than one way to implement MVVM, and many different techniques are considered part of MVVM. For this reason, there are several different third-party MVVM frameworks supporting the various XAML-based platforms, including Windows App SDK. However, these frameworks generally include multiple services for implementing decoupled architecture, making the exact definition of MVVM somewhat ambiguous.

Although sophisticated MVVM frameworks can be very useful, especially for enterprise-scale projects, there is typically a cost associated with adopting any particular pattern or technique, and the benefits are not always clear, depending on the scale and size of your project. Fortunately, you can adopt only those techniques that provide a clear and tangible benefit, and ignore others until you need them.

In particular, you can get a lot of benefit simply by understanding and applying the full power of data binding and separating your app logic into the layers described earlier. This can be achieved using only the capabilities provided by the Windows App SDK, and without using any external frameworks. In particular, the [{x:Bind} markup extension](/windows/uwp/xaml-platform/x-bind-markup-extension) makes data binding easier and higher performing than in previous XAML platforms, eliminating the need for a lot of the boilerplate code required earlier.

For additional guidance on using basic, out-of-the-box MVVM, check out the [Customers Orders Database UWP sample](https://github.com/Microsoft/Windows-appsample-customers-orders-database) on GitHub. Many of the other [UWP app samples](https://github.com/Microsoft?q=windows-appsample
) also use a basic MVVM architecture, and the [Traffic App UWP sample](https://github.com/Microsoft/Windows-appsample-trafficapp) includes both code-behind and MVVM versions, with notes describing the [MVVM conversion](https://github.com/Microsoft/Windows-appsample-trafficapp/blob/MVVM/MVVM.md).

## See also

### Topics

[Data binding in depth](data-binding-in-depth.md)
[{x:Bind} markup extension](/windows/uwp/xaml-platform/x-bind-markup-extension)

### UWP MVVM Samples

[Customers Orders Database sample](https://github.com/Microsoft/Windows-appsample-customers-orders-database)
[VanArsdel Inventory sample](https://github.com/Microsoft/InventorySample)
[Traffic App sample](https://github.com/Microsoft/Windows-appsample-trafficapp)
Loading

0 comments on commit deee97e

Please sign in to comment.