Источники данных ListView

Используется Xamarin.FormsListView для отображения списков данных. В этой статье объясняется, как заполнить ListView данные данными и как привязать данные к выбранному элементу.

ItemsSource

Объект ListView заполняется данными с помощью ItemsSource свойства, которое может принимать любую коллекцию, реализующую IEnumerable. Самый простой способ заполнения включает ListView в себя использование массива строк:

<ListView>
      <ListView.ItemsSource>
          <x:Array Type="{x:Type x:String}">
            <x:String>mono</x:String>
            <x:String>monodroid</x:String>
            <x:String>monotouch</x:String>
            <x:String>monorail</x:String>
            <x:String>monodevelop</x:String>
            <x:String>monotone</x:String>
            <x:String>monopoly</x:String>
            <x:String>monomodal</x:String>
            <x:String>mononucleosis</x:String>
          </x:Array>
      </ListView.ItemsSource>
</ListView>

Эквивалентный код на C# выглядит так:

var listView = new ListView();
listView.ItemsSource = new string[]
{
  "mono",
  "monodroid",
  "monotouch",
  "monorail",
  "monodevelop",
  "monotone",
  "monopoly",
  "monomodal",
  "mononucleosis"
};

Список строк в ListView

Этот подход заполняет ListView список строк. По умолчанию ListView вызовет ToString и отобразит результат в каждой TextCell строке. Сведения о том, как отображаются данные, см. в разделе "Внешний вид ячейки".

Так как ItemsSource он был отправлен в массив, содержимое не будет обновляться как базовый список или изменения массива. Если вы хотите, чтобы ListView автоматически обновлялся при добавлении, удалении и изменении в базовом списке, вам потребуется использовать элемент ObservableCollection. ObservableCollection определяется System.Collections.ObjectModel и точно так же List, как, за исключением того, что он может уведомлять о ListView любых изменениях:

ObservableCollection<Employee> employees = new ObservableCollection<Employee>();
listView.ItemsSource = employees;

//Mr. Mono will be added to the ListView because it uses an ObservableCollection
employees.Add(new Employee(){ DisplayName="Mr. Mono"});

Привязка данных

Привязка данных — это "клей", который привязывает свойства объекта пользовательского интерфейса к свойствам определенного объекта CLR, например класса в модели представления. Привязка данных полезна, так как она упрощает разработку пользовательских интерфейсов, заменив много скучного кода.

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

Дополнительные сведения о привязке данных см. в статье "Основы привязки данных", которая является частью четырех Xamarin.Forms серии статей XAML Basics.

Привязка ячеек

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

Класс сотрудника:

public class Employee
{
    public string DisplayName {get; set;}
}

Создается ObservableCollection<Employee> , задается в качестве ListViewItemsSourceсписка, а список заполняется данными:

ObservableCollection<Employee> employees = new ObservableCollection<Employee>();
public ObservableCollection<Employee> Employees { get { return employees; }}

public EmployeeListPage()
{
    EmployeeView.ItemsSource = employees;

    // ObservableCollection allows items to be added after ItemsSource
    // is set and the UI will react to changes
    employees.Add(new Employee{ DisplayName="Rob Finnerty"});
    employees.Add(new Employee{ DisplayName="Bill Wrestler"});
    employees.Add(new Employee{ DisplayName="Dr. Geri-Beth Hooper"});
    employees.Add(new Employee{ DisplayName="Dr. Keith Joyce-Purdy"});
    employees.Add(new Employee{ DisplayName="Sheri Spruce"});
    employees.Add(new Employee{ DisplayName="Burt Indybrick"});
}

Предупреждение

Хотя объект ListView обновляется в ответ на изменения в его базовой ObservableCollectionсреде, ListView обновление не будет обновляться, если другой ObservableCollection экземпляр назначается исходной ObservableCollection ссылке (например, employees = otherObservableCollection;).

Следующий фрагмент кода демонстрирует ListView привязку к списку сотрудников:

<?xml version="1.0" encoding="utf-8" ?>
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
             xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
             xmlns:constants="clr-namespace:XamarinFormsSample;assembly=XamarinFormsXamlSample"
             x:Class="XamarinFormsXamlSample.Views.EmployeeListPage"
             Title="Employee List">
  <ListView x:Name="EmployeeView"
            ItemsSource="{Binding Employees}">
    <ListView.ItemTemplate>
      <DataTemplate>
        <TextCell Text="{Binding DisplayName}" />
      </DataTemplate>
    </ListView.ItemTemplate>
  </ListView>
</ContentPage>

В этом примере XAML определяется объект ContentPage , содержащий объект ListView. Источник данных для ListView задается с помощью атрибута ItemsSource. Макет каждой строки в ItemsSource определяется в элементе ListView.ItemTemplate. Это приводит к следующим снимкам экрана:

ListView с помощью привязки данных

Предупреждение

ObservableCollection не является потокобезопасной. Изменение причины возникновения обновлений ObservableCollection пользовательского интерфейса в том же потоке, который выполнял изменения. Если поток не является основным потоком пользовательского интерфейса, это приведет к исключению.

Привязка SelectedItem

Часто необходимо привязать к выбранному элементу элемента ListView, а не использовать обработчик событий для реагирования на изменения. Для этого в XAML необходимо привязать SelectedItem свойство:

<ListView x:Name="listView"
          SelectedItem="{Binding Source={x:Reference SomeLabel},
          Path=Text}">
 …
</ListView>

ПредположимlistView, что 's ItemsSource является списком строк, SomeLabel его Text свойство привязано к .SelectedItem