Опубликован: 12.02.2013 | Уровень: для всех | Доступ: платный
Лекция 5:

Создание приложений Silverlight

8.4. Отображение списков данных

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

В качестве примера рассмотрим создание списка клиентов компании. Информация о клиентах включает: имя клиента, адрес и идентификатор. Класс Customer может выглядеть так:

public class Customer
{
    public string Name { get; set; }
    public string Address { get; set; }
    public int ID { get; set; }

    public Customer(string inName, string inAddress, int inID)
    {
        Name = inName;
        Address = inAddress;
        ID = inID;
    }
}

Этот класс имеет единственный метод, который является конструктором, принимающим три параметра.

Теперь нужно сохранить список клиентов. Лучший способ для хранения списков объектов — использование класса List, который входит в состав языка C#. Можно создать класс Customers, содержащий имя списка клиентов и сам список:

public class Customers
{
    public string Name { get; set; }

    public List<Customer> CustomerList;

    public Customers(string inName)
    {
        Name = inName;
        CustomerList = new List<Customer>();
    }
}

Класс Customers содержит единственный метод, который является конструктором класса. Он определяет имя списка и создает пустой список. Используя этот класс, можно создать новый список таким образом:

Customers mailCustomers = new Customers("Список клиентов");

Теперь нужно заполнить созданный пустой список информацией о клиентах.

Создание данных для списка

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

public static Customers MakeTestCustomers()
{
    string[] firstNames = new string[] { "Rob", "Jim", "Joe", "Nigel", "Sally",
        "Tim"};
    string[] lastsNames = new string[] { "Smith", "Jones", "Bloggs", "Miles",
        "Wilkinson", "Brown" };
    Customers result = new Customers("Тестовый список");
    int id = 0;

    foreach (string lastName in lastsNames)
    {
        foreach (string firstname in firstNames)
        {
            // формирование имени клиента
            string name = firstname + " " + lastName;
            // добавление клиента в список
            result.CustomerList.Add(new Customer(name, name + "'s House", id));
            // увеличение значения идентификатора для следующего клиента
            id++;
        }
    }
    return result;
}

В этом коде создается 36 клиентов комбинированием всех заданных имен и фамилий. У каждого клиента свой уникальный идентификационный номер. Метод MakeTestCustomers является статическим, чтобы не нужно было создавать список перед получением тестовых данных. Теперь можно использовать полученный список в программе:

customerList = Customers.MakeTestCustomers();

Использование элемента StackPanel для вывода списка на экран

Следующим шагом будет вывод полученного списка клиентов на экран Windows Phone. Для этого можно поместить имя каждого клиента в отдельный элемент TextBlock. Требуется, чтобы элементы могли размещаться на экране независимо от их количества. Для этого можно использовать элемент StackPanel:

<StackPanel HorizontalAlignment="Left" Margin="0,0,0,0" Name="customersStackPanel"
    VerticalAlignment="Top" />

Элементы TextBlock можно создавать в программе с помощью следующего кода:

customers = Customers.MakeTestCustomers();

foreach (Customer c in customers.CustomerList)
{
    TextBlock customerBlock = new TextBlock();
    customerBlock.Text = c.Name;
    customersStackPanel.Children.Add(customerBlock);
}

В этом коде для каждого клиента создается элемент TextBlock, в котором в текстовое поле записывается имя клиента, после чего этот элемент добавляется customersStackPanel. Как видно из примера, визуальные объекты можно создавать как в XAML-коде, так и в коде программы на C#.

Полученная программа может выводить на экран список любого размера (рис. 8.7).

Список клиентов

Рис. 8.7. Список клиентов

Однако, некоторые элементы не видны на экране, поскольку находятся за его пределами. Это является существенным недостатком. Решить проблему можно, добавив в программу возможность прокрутки экрана вверх и вниз, чтобы пользователь мог увидеть остальную часть списка. Такую возможность предоставляет элемент ScrollViewer, если в него поместить элемент StackPanel:

<ScrollViewer>
  <StackPanel HorizontalAlignment="Left" Margin="9,6,0,0" Name="customersStackPanel"
      VerticalAlignment="Top" />
</ScrollViewer>

Теперь в приложении отображается полоса прокрутки, и пользователь может прокручивать экран вверх и вниз, чтобы просмотреть список полностью.

Использование элемента ListBox для отображения списка элементов

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

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

<DataTemplate>
  <StackPanel>
    <TextBlock Text="{Binding Name}" />
    <TextBlock Text="{Binding Address}" />
  </StackPanel>
</DataTemplate>

Этот шаблон данных определяет, что информация должна выводиться в элемент StackPanel, который содержит два элемента TextBlock с именами Name и Address. В соответствии с этим шаблоном будут выводиться две строки: в первой строке указывается имя клиента, во второй — его адрес. При этом, в шаблоне не указано значение идентификатора, поскольку нам не нужно выводить это значение на экран.

Использование шаблона DataTemplate для списка. Шаблон данных указывает Silverlight как нужно выводить на экран свойства объекта. Его можно использовать для вывода списка клиентов на экран. Для этого нужно поместить шаблон DataTemplate в секции ItemTemplate элемента ListBox, который выведет на экран информацию о клиентах:

<ListBox Name="customerList">
    <ListBox.ItemTemplate>
        <DataTemplate>
            <StackPanel>
                <TextBlock Text="{Binding Name}" />
                <TextBlock Text="{Binding Address}" />
            </StackPanel>
        </DataTemplate>
    </ListBox.ItemTemplate>
</ListBox>

Этот код настраивает внешний вид списка данных, вывод которого на экран осуществляет элемент customerList. Теперь нужно указать список данных, которые должны выводиться на экран:

customers = Customers.MakeTestCustomers();
customerList.ItemsSource = customers.CustomerList;

Этот код получает тестовый список клиентов, который присваивается свойству ItemSource элемента customerList. Элемент ListBox выведет на экран каждый объект в наборе как элемент списка (рис. 8.8).

Список клиентов с адресами

Рис. 8.8. Список клиентов с адресами

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

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

Преимущество использования встроенных стилей заключается в том, что они используют различные цветовые схемы Windows Phone. К элементам TextBlock в шаблоне DataTemplate можно добавить названия используемых стилей:

<DataTemplate>
  <StackPanel>
    <TextBlock Text="{Binding Name}"
        Style="{StaticResource PhoneTextExtraLargeStyle}" />
    <TextBlock Text="{Binding Address}" 
        Style="{StaticResource PhoneTextSubtleStyle}" />
  </StackPanel>
</DataTemplate>

В этом коде используются встроенные стили ExtraLargeStyle для имени клиента и SubtleStyle для адреса. Теперь список визуально воспринимается гораздо лучше (рис. 8.9).

Список клиентов с адресами, использующий встроенные стили

Рис. 8.9. Список клиентов с адресами, использующий встроенные стили

Выбор элементов списка. Следующим шагом будет добавление в программу возможности редактирования данных. При выборе одного из элементов списка должен отображаться экран для редактирования выбранного элемента (рис. 8.10).

Экран приложения для редактирования информации о выбранном клиенте

Рис. 8.10. Экран приложения для редактирования информации о выбранном клиенте

При выборе элемента списка элемент ListBox генерирует событие SelectionChanged, для которого можно создать обработчик. Обработчик может выглядеть так:

private void customerList_SelectionChanged(object sender, SelectionChangedEventArgs e)
{
    // получение содержимого выбранного элемента
    Customer selectedCustomer = customerList.SelectedItem as Customer;

    MessageBox.Show("Выбран элемент " + selectedCustomer.Name);
}

Класс customerList содержит свойство SelectedItem, который является ссылкой на выбранный объект. В этом коде выбранный объект приводится к типу Customer, и программа выводит на экран окно с сообщением, в котором указано имя выбранного клиента.

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

park mr
park mr
Таиланд, thai
An Nguyen
An Nguyen
Вьетнам, 30/9 Thong Nhat street, ward 13, Go Vap district