Вы зашли как: Гость
24.08.2017 10:51 | dronov_va

Пятая часть статьи, посвящённой привязке данных и её использованию при разработке универсальных приложений Windows 10.

4. Привязка списков



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

Понятно, что списки имеет смысл привязывать к элементам управления списочного типа: ListBox, ComboBox, ListView и GridView. Если привязываемый список хранит объекты, то для элемента управления придётся задать шаблон, который определит внешний вид его пунктов.


4.1. Простейший случай: привязка неизменяемого списка, хранящего элементарные значения

Проще всего, если список, который станет источником привязки, хранит в качестве элементов значения элементарного типа, и набор его элементов в процессе работы приложения не изменяется. В таком случае нам даже не придётся создавать у элемента-приёмника шаблон, а в качестве списка-источника мы можем использовать объект любого подходящего класса.

Создадим в Visual Studio новый проект под именем Bindings4. Откроем интерфейсный код начальной страницы и поместим на страницу обычный элемент-список - ListBox (в панели Панель элементов он находится в "ветви" Все элементы управления XAML). Зададим для него такие параметры:

  • Width - Auto;
  • Height - Auto;
  • HorizontalAlignment - Stretch;
  • VerticalAlignment - Stretch;
  • Margin - 0 пикселов со всех сторон.



В качестве списка-источника мы используем объект обобщённого класса List<T> из пространства имён System.Collection.Generic. Этот класс не отличается большим потреблением системных ресурсов, а его возможностей хватит для наших нужд.

Ради уменьшения потребления системных ресурсов и ускорения запуска приложения мы создадим в новом приложении необъектную привязку (она описывалась в параграфе 3.6). А, поскольку содержимое списка-источника не меняется, и, как следствие, нет нужды отслеживать происходящие в нём изменения, мы со спокойной душой можем сделать привязку одномоментной.

Откроем файл с функциональным кодом начальной страницы, создадим в классе страницы поле data (создавать под эту задачу полноценное свойство большой нужды нет), которое будет хранить сам список, и добавим в конструктор класса код, который создаст список, заполнит его какими-либо элементами и сохранит в вышеупомянутом поле. В результате объявление класса страницы должно принять такой вид:

public sealed partial class MainPage : Page
{
    public List<string> data;
   
    public MainPage()
    {
        this.InitializeComponent();

        this.data = new List<string>();
        this.data.Add("XAML");
        this.data.Add("C#");
        this.data.Add("C++");
        this.data.Add("Visual Basic .NET");
        this.data.Add("JavaScript");
        this.data.Add("Python");
        this.data.Add("TypeScript");
        this.data.Add("F#");
    }
}



Здесь мы в качестве примера заполнили список-источник названиями языков программирования, поддерживаемых Visual Studio. Метод Add класса List<T> добавляет в список переданное ему единственным аргументом значение и не возвращает результата.

В элементе управления ListBox (и аналогичных ему) список, из которого будут взяты данные для формирования пунктов, задаётся с помощью свойства ItemsSource. Оно имеет тип System.Object, - следовательно, мы можем присвоить ему объект любого класса.

Переключимся на интерфейс страницы и найдём в редакторе XAML-кода тег <ListBox>, создающий наш элемент-список. Добавим в него следующий фрагмент, создающий необъектную привязку свойства ItemsSource к полю data класса страницы:

<ListBox ItemsSource="{x:Bind data, Mode=OneTime}"/>



Сохраним проект и запустим приложение на выполнение. Мы увидим список, заполненный названиями языков программирования (рис. 12). Наше приложение работает!


Рис. 12. Приложение Bindings4




4.2. Более сложный случай: привязка неизменяемого списка, хранящего объекты

Если список-источник хранит элементы, являющиеся не элементарными значениями, а объектами какого-либо класса, привязка выполняется точно таким же образом, как и в предыдущем случае. Однако для списка придётся указать шаблон, который задаст внешний вид пунктов и данные, которые будут выведены в них.

Создадим новый проект Bindings5. Поместим на его начальную страницу элемент-список ListBox и укажем для него те же параметры, что задавали, разрабатывая предыдущее приложение.

Далее добавим в проект новый файл программного кода PL.cs, в котором объявим класс PL, хранящий название и описание языка программирования. Вот код, объявляющий этот класс:

public class PL
{
    public string name;
    public string description;

    public PL(string name, string description)
    {
        this.name = name;
        this.description = description;
    }
}



Здесь мы создали два поля - name и description, - в которых будут храниться, соответственно, название и описание языка программирования. (Создавать полноценные свойства под это нет особой необходимости.) Также мы объявили конструктор, который примет в качестве параметров эти самые имя и описание и занесёт их в поля вновь созданного объекта.

Откроем файл функционального кода начальной страницы, создадим в классе страницы поле data, в котором будет храниться список, и добавим в конструктор класса код, который создаст и заполнит этот список. После чего объявление класса страницы будет выглядеть следующим образом:

public sealed partial class MainPage : Page
{
    public List<PL> data;

    public MainPage()
    {
        this.InitializeComponent();

        this.data = new List<PL>();
        this.data.Add(new PL("XAML", "Язык описания интерфейса страниц"));
        this.data.Add(new PL("C#", "Компилируемый язык программирования приложений под .NET"));
        this.data.Add(new PL("C++", "Компилируемый язык программирования общего назначения"));
        this.data.Add(new PL("Visual Basic .NET", "Компилируемый язык программирования приложений под .NET"));
        this.data.Add(new PL("JavaScript", "Интерпретируемый язык для Web-программирования"));
        this.data.Add(new PL("Python", "Интерпретируемый язык программирования общего назначения"));
        this.data.Add(new PL("TypeScript", "Интерпретируемый язык Web-программирования"));
        this.data.Add(new PL("F#", "Компилируемый язык функционального программирования"));
    }
}

this.data.Add(new PL("TypeScript", "Интерпретируемый язык Web-программирования"));
this.data.Add(new PL("F#", "Компилируемый язык функционального программирования"));
}
}[/code]

Переключимся на интерфейсный код начальной страницы и в редакторе XAML-кода найдём тег <ListBox>, создающий элемент-список. Допишем в него код, устанавливающий привязку свойства ItemsSource к полю data страницы:

[code]<ListBox ItemsSource="{x:Bind data, Mode=OneTime}"/>[/code]

Сохраним проект и запустим приложение на выполнение. Приложение запустится, но список выведет только имена класса, на основе которого были созданы объекты - элементы списка-источника (рис. 13).


Рис. 13. Приложение Bindings5 в процессе разработки. Вместо названий и описаний языков программирования в элементе-списке выводятся имена класса PL



Дело здесь в следующем. При формировании пунктов элемента-списка платформа UWP берёт элементы списка-источника, преобразует их в строковый вид, вызвав у них метод ToString, и использует возвращённые этим методом строки в качестве надписей для этих пунктов. Но у объектов класса PL, которые хранит наш список, этот метод, унаследованный от родителя, возвращает строковое имя класса. Его-то мы и наблюдаем в каждом пункте элемента-списка на рис. 13.

Чтобы вывести в пунктах элемента-списка значения, хранящиеся в полях и свойствах объектов - элементов списка-источника, нужно задать для списка шаблон пункта, на основе которого будут сформированы пункты. Этот шаблон чем-то похож на страницу приложения: он содержит контейнер, в котором располагаются элементы интерфейса, выводящие данные.

Шаблон пункта должен представлять собой объект класса DataTemplate, единственным потомком которого является тот самый контейнер с элементами интерфейса. А указывается этот шаблон с применением свойства ItemTemplate элемента-списка ListBox и аналогичных ему элементов управления.

Для разработки шаблонов пунктов Visual Studio не предоставляет каких-либо визуальных инструментов. Нам придётся ввести необходимый XAML-код вручную.

Найдём тег <ListBox>, создающий наш элемент-список. Исправим его таким образом, чтобы он выглядел, как показано ниже.

[code]<ListBox ItemsSource="{x:Bind data, Mode=OneTime}">
<ListBox.ItemTemplate>
<DataTemplate x:DataType="local:PL">
<StackPanel>
<TextBlock Text="{x:Bind name}" FontWeight="Bold"/>
<TextBlock Text="{x:Bind description}"/>
</StackPanel>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>[/code]

Отметим следующие примечательные моменты:

  • Мы задали для самого шаблона пункта (DataTemplate) тип данных, которые будут выводиться в пункте списка, - наш класс PL. (Тип данных указывается в параметре x:DataType.) Это обязательно следует сделать для того, чтобы компилятор "знал" этот тип, - в противном случае он не сможет сгенерировать Исполняемый код, реализующий необъектную привязку.
  • В самом шаблоне мы применили контейнер-стопку StackPanel. Этот контейнер требует для работы меньше системных ресурсов, чем привычная нам сетка.
  • Для вывода значений полей мы применили элементы-надписи (TextBlock).
  • Свойство Text каждой из надписей, что находится в шаблоне, мы привязали к соответствующему полю класса PL, указанного в качестве типа данных у шаблона пункта.
  • Для первой надписи шаблона, выводящей название языка программирования, мы указали полужирный шрифт - просто чтобы выделить его.



Кстати, установив текстовый курсор на открывающий тег, создающий какой-либо из входящих в состав шаблона элементов интерфейса, мы сможем править его параметры в панели Свойства.

Теперь сохраним проект и запустим приложение. Вот теперь оно работает как положено - см. рис. 14.


Рис. 14. Приложение Bindings5 в законченном виде. В элементе-списке выводятся названия и описания языков программирования




4.3. Привязка к методам

В версии 1607 Windows 10 (также известной как Anniversary Update) появилась любопытная и полезная возможность - связывание приёмника со статическим методом источника (привязка к методам), а не с полем или свойством. Эта возможность поддерживается только необъектной привязкой.

Внимание!
Поддерживается привязка только к статическим методам классов. Привязка к обычным методам невозможна.

Вызов метода задаётся в параметрах привязки в таком же виде, как и в функциональном коде. В качестве аргумента может быть указана как константа, так и значение одного из полей или свойств источника.

Для того чтобы успешно использовать в приложении привязку к методам, следует указать в качестве минимальной версию 1607 Windows 10 (Anniversary Update) или более позднюю.

  • Если новый проект только создаётся, следует выбрать в раскрывающемся списке Минимальная диалогового окна Новый универсальный проект для Windows (см. рис. 2) пункт Windows 10 Anniversary Update (10.0; сборка 14393).
  • Если же проект уже создан и находится в работе, дело несколько усложняется. Найдём в панели Обозреватель решений "ветвь", представляющую проект, щёлкнем на ней правой кнопкой мыши и выберем в появившемся контекстном меню пункт Свойства. На экране появится окно параметров проекта (рис. 15).


    Рис. 15. Окно параметров проекта



    В списке слева выберем пункт Приложение, найдём группу элементов управления Нацеливание, а в ней - раскрывающийся список Минимальная версия. Выберем в этом списке всё тот же пункт Windows 10 Anniversary Update (10.0; сборка 14393).

    Внимание!
    Возможно, после этого Visual Studio попросит нас установить недостающий компонент - пакет средств разработчика для программирования под эту версию Windows. Ответим положительно на появившееся на экране предупреждение, после чего, когда появится окно установщика Visual Studio, закроем среду разработки и выполним все инструкции установщика. Как только установка завершится, снова запустим Visual Studio, откроем наш проект, выведем окно его параметров и выберем в списке Минимальная версия нужный пункт. Visual Studio предложит нам перезагрузить проект, что мы и сделаем.



Давайте сделаем так, чтобы пункт XAML списка в нашем приложении Bingings5 выводился курсивным шрифтом.

Сначала мы добавим в класс PL публичный статический метод GetFontStyle, который в качестве единственного параметра примет строковое название языка программирования, а в качестве результата вернёт один из элементов перечисления FontStyle (объявлено в пространстве имён Windows.UI.Text), указывающий начертание шрифта - обычное или курсивное.

Потом мы свяжем метод GetFontStyle со свойством FontStyle, задающим начертание шрифта, обеих надписей, входящих в состав шаблона пункта. В вызове этого метода в качестве аргумента мы укажем значение поля name класса PL.

Откроем файл с объявлением класса PL и дополним его следующим кодом:

[code]using Windows.UI.Text;

. . .

public class PL
{
. . .

public static FontStyle GetFontStyle(string name)
{
return (name == "XAML") ? FontStyle.Italic : FontStyle.Normal;
}
}[/code]

Не забудем добавить в начало кода выражение, выполняющее присоединение пространства имён Windows.UI.Text.

Далее откроем файл с интерфейсным кодом начальной страницы, найдём в редакторе кода тег <TextBlock>, создающий первую надпись шаблона, и вставим в него фрагмент, устанавливающий привязку:

[code]<TextBlock . . . FontStyle="{x:Bind local:PL.GetFontStyle(name)}"/>[/code]

Здесь следует принять во внимание тот факт, что статические методы вызываются у класса, а имя класса, объявленного в приложении, должно предваряться префиксом local, указывающим на пространство имён приложения.

Точно такой же фрагмент кода вставим в тег, создающий вторую надпись из имеющихся в шаблоне пункта.

Сохраним проект и запустим приложение. Вот теперь текст пункта списка, описывающего язык XAML, выводится курсивом (рис. 16).


Рис. 16. Приложение Bindings5 после модификации. Пункт списка, описывающий язык XAML, выводится курсивным шрифтом




Дополнительные материалы




Окончание следует...


Владимир Дронов, MSInsider.ru Team
Май 2017

Комментарии

Комментариев нет...
Для возможности комментировать войдите в 1 клик через

По теме

Акции MSFT
82.40 0.00
Акции торгуются с 17:30 до 00:00 по Москве
Мы на Facebook
Мы ВКонтакте
Все права принадлежат © MSInsider.ru (ex TheVista.ru), 2017
Сайт является источником уникальной информации о семействе операционных систем Windows и других продуктах Microsoft. Перепечатка материалов возможна только с разрешения редакции.
Работает на WMS 2.34 (Страница создана за 0.123 секунд (Общее время SQL: 0.009 секунд - SQL запросов: 31 - Среднее время SQL: 0.00029 секунд))