Xamarin.Forms Projects
上QQ阅读APP看书,第一时间看更新

Creating the MainView

Now that we are done with the ViewModels, let's create the skeleton code and the XAML needed for the views. The first view that we are going to create is the MainView, which is the view that will be loaded first:

  1. Create a folder named Views in the .NET Standard library.
  2. Right-click the Views folder, select Add, and then click New Item....
  3. Select Xamarin.Forms under the Visual C# Items node on the left.
  1. Select Content Page and name it MainView.
  2. Click Add to create the page:

Let's add some content to the newly created view:

  1. Open MainView.xaml.
  2. Remove all the template code below the ContentPage root node and add the XAML code marked in bold in the following code:
<?xml version="1.0" encoding="utf-8"?>
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
xmlns:local="clr-namespace:DoToo"
x:Class="DoToo.Views.MainView"
Title="Do Too!">

<ContentPage.ToolbarItems>
<ToolbarItem Text="Add" />
</ContentPage.ToolbarItems>

<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="auto" />
<RowDefinition Height="*" />
</Grid.RowDefinitions>

<Button Text="Toggle filter" />

<ListView Grid.Row="1">
</ListView>
</Grid>
</ContentPage>

To be able to access custom converters, we need to add a reference to a local namespace. The line xmlns:local="clr-namespace:DoToo" defines this namespace for us. We will not be using it directly in this case, but it's a good idea to have a local namespace defined. If we create custom controls, we can then access these by writing something like <local:MyControl />.

The Title property on the ContentPage gives the page a title. Depending on the platform we are running on, the title is displayed differently. If we are using a standard navigation bar, it will be displayed at the top in both iOS and Android, for example. A page should always have a title.

The ContentPage.Toolbar node defines a toolbar item for adding new to-do items. It will also be rendered differently based on the platform, but it will always follow the platform-specific UI guidelines.

A page in Xamarin.Forms (and also an XML document in general) can only have one root node. The root node in a Xamarin.Forms page will populate the Content property of the page itself. Since we want our MainView to contain a list of items and a button at the top to toggle a filter (to switch between all items and only active items), we need to add a Layout control to position them on the page. The Grid is a control that allows you to partition the available space based on rows and columns.

For our MainView, we want to add two rows. The first row is a space calculated by the height of the button (Height="auto") and the second row takes up all of the remaining available space for the Listview (Height="*"). Elements, like the ListView, are positioned in the grid using the Grid.Row and Grid.Column attributes. Both of these properties default to 0 if they are not specified, just like the Button.

If you are interested in how the Grid works, you should search for more information about Xamarin.Forms Grid on the internet or study the official documentation at  https://docs.microsoft.com/en-us/xamarin/xamarin-forms/user-interface/layouts/grid.

We also need to wire up the ViewModel to the view. This can be done by passing the ViewModel in the constructor of the view:

  1. Open up the code-behind file of the MainView by expanding the MainView.xaml file in the Solution Explorer.
  2. Add a using DoToo.ViewModels statement at the top of the following file the existing using statements.
  3. Modify the constructor of the class to look like the following code by adding the code marked in bold:
public MainView(MainViewModel viewModel)
{
InitializeComponent();
viewModel.Navigation = Navigation;
BindingContext = viewModel;
}

We follow the same pattern as we did with the ViewModels by passing any dependencies through the constructor. A view is always dependent on a ViewModel. To simplify the project, we also assign the Navigation property of the page directly to the Navigation property defined in the ViewModel base class. In a larger project, we might want to abstract this property as well, to make sure that we separate the ViewModels completely from Xamarin.Forms. For the sake of this app, however, it is OK to reference it directly.

Lastly, we assign the ViewModel to the BindingContext of the page. This tells the Xamarin.Forms binding engine to use our ViewModel for the bindings that we will create later on.