Визуальные компоненты ContentView

Создание визуальных компонентов

Последнее обновление: 13.01.2021

Нередко на различных страницах одного приложения и даже в разных приложениях могут использоваться повторяющиеся элементы разметки xaml. Например, форма входа, предусматривающая ввод логина и пароля, или форма поиска. Такая форма входа может использоваться в самых различных приложениях для авторизации пользователя. То же самое относится к форме поиска, так как вне зависимости от страницы или приложения она, как правило, будет содержать текстовое поле и кнопку. И чтобы не повторяться, Xamarin Forms позволяет оформить повторяющиеся элементы в виде отдельного визуального компонента, который можно использовать повторно в разных проектах.

Для создания визуальных компонентов применяется класс ContentView. Чтобы создать первый визуальный компонент, который будет представлять окно поиска, добавим в главный проект новый элемент по типу ContentView (C#), который назовем SearchView:

Forms ContentView в Xamarin Forms

После этого в проект добавится обычный класс на языке C#, который будет иметь примерно следующий код:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

using Xamarin.Forms;

namespace HelloApp
{
    public class SearchView : ContentView
    {
        public SearchView()
        {
            Content = new StackLayout
            {
                Children = {
                    new Label { Text = "Welcome to Xamarin.Forms!" }
                }
            };
        }
    }
}
Компонент ContentView в Xamarin Forms

Изменим его код следующим образом:

using Xamarin.Forms;

namespace HelloApp
{
    public delegate void SearchEventHandler(string text);
	
    public class SearchView : ContentView
    {
        public event SearchEventHandler Search;
        public SearchView()
        {
            Button searchBtn = new Button { Text = "Поиск" };
            Entry searchEntry = new Entry { HorizontalOptions = LayoutOptions.FillAndExpand };
			
            searchBtn.Clicked += (sender, e) => Search?.Invoke(searchEntry.Text);
            Content = new StackLayout
            {
                Orientation = StackOrientation.Horizontal,
                Spacing = 5,
                Children =
                {
                    searchEntry,
                    searchBtn
                }
            };
        }
    }
}

В коде компонента SearchView определены текстовое поле и кнопка, а также событие Search, которое вызывается при нажатии на кнопку. Данное событие будет представлять делегат SearchEventHandler. И через это событие внешний код сможет получить введенное значение и выполнить с ним какие-нибудь действия.

В коде страницы MainPage определим следующее содержимое:

using System.Collections.Generic;
using System.Linq;
using Xamarin.Forms;

namespace HelloApp
{
    public partial class MainPage : ContentPage
    {
        public MainPage()
        {
            List<string> users = new List<string>()
            {
                "Иван Иванов",
                "Олег Кузнецов",
                "Денис Петров",
                "Иван Сидоров",
                "Петр Денисов"
            };

            ListView usersList = new ListView
            {
                ItemsSource = users
            };
            

            SearchView searchView = new SearchView();
            searchView.Search += (text) =>
            {
                if(!string.IsNullOrEmpty(text))
                {
                    usersList.ItemsSource = users.Where(u=>u.Contains(text));
                }
                else
                {
                    usersList.ItemsSource = users;
                }
            };
            Content = new StackLayout { Children = { searchView, usersList } };
        }
    }
}

Для вывода списка пользователей определен элемент ListView. В обработчике события Search происходит фактически фильтрация списка.

Применение ContentView в Xamarin

Аналогично можно использовать ContentView и в коде xaml. Допустим, у нас есть страница MainPage.xaml:

<?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:HelloApp;assembly=HelloApp"
             x:Class="HelloApp.MainPage">
  <StackLayout>
    <local:SearchView Search="SearchUsers"></local:SearchView>
    <ListView x:Name="usersList" />
  </StackLayout>
</ContentPage>

А в коде страницы пропишем установку списка и обработчик события Search:

using System.Collections.Generic;
using System.Linq;

using Xamarin.Forms;

namespace HelloApp
{
    public partial class MainPage : ContentPage
    {
        List<string> users;

        public MainPage()
        {
            InitializeComponent();

            users = new List<string>()
            {
                "Иван Иванов",
                "Олег Кузнецов",
                "Денис Петров",
                "Иван Сидоров",
                "Петр Денисов"
            };
            usersList.ItemsSource = users;
        }

        private void SearchUsers(string text)
        {
            if (!string.IsNullOrEmpty(text))
            {
                usersList.ItemsSource = users.Where(u => u.Contains(text));
            }
            else
            {
                usersList.ItemsSource = users;
            }
        }
    }
}

Результат в данном случае будет аналогичен работе страницы MainPage.

Определение ContentView в XAML

Не всем удобно определять интерфейс в коде C#, кому-то будет комфортнее работать с XAML. Для этого добавим в проект новый элемент по типу ContentView Xaml, который назовем SearchPlugin:

Forms ContentView Xaml в Xamarin Forms

Добавленный файл xaml во многом напоминает код xaml обычной страницы, только в данном случае определяется не ContentPage, а элемент ContentView. И далее изменим код xaml добавленного файла следующим образом:

<?xml version="1.0" encoding="utf-8" ?>
<ContentView xmlns="http://xamarin.com/schemas/2014/forms"
             xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
             x:Class="HelloApp.SearchPlugin">
  <StackLayout Orientation="Horizontal" Spacing="5">
    <Entry x:Name="searchEntry" HorizontalOptions="FillAndExpand" />
    <Button Clicked="OnClicked" Text="Поиск" />
  </StackLayout>
</ContentView>

И также изменим файл связанного кода:

using System;
using Xamarin.Forms;

namespace HelloApp
{
	public delegate void SearchPluginEventHandler(string text);
    public partial class SearchPlugin : ContentView
    {
        public event SearchPluginEventHandler Search;

        public SearchPlugin()
        {
            InitializeComponent();
        }
        private void OnClicked(object sender, EventArgs e)
        {
            Search?.Invoke(searchEntry.Text);
        }
    }
}

И далее данный класс мы сможем использовать аналогичным образом:

<?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:HelloApp;assembly=HelloApp"
             x:Class="HelloApp.MainPage">
  <StackLayout>
    <local:SearchPlugin Search="SearchUsers"></local:SearchPlugin>
    <ListView x:Name="usersList" />
  </StackLayout>
</ContentPage>
Помощь сайту
Юмани:
410011174743222
Перевод на карту
Номер карты:
4048415020898850