Опубликован: 12.02.2013 | Доступ: свободный | Студентов: 791 / 47 | Длительность: 17:51:00
Специальности: Программист
Самостоятельная работа 6:

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

Аннотация: Цель работы: изучение возможностей использования привязки данных к визуальным элементам Silverlight.

Основные теоретические сведения

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

Привязка данных может работать в любом направлении. Можно связать текст элемента TextBox с приложением таким образом, чтобы при изменении текста в этом текстовом поле приложение было об этом уведомлено. Также можно связать элемент TextBlock с объектом так, чтобы при изменении свойства объекта содержимое элемента TextBlock соответственно обновлялось. Это пример двунаправленной привязки, когда программа может сама изменить элемент и отреагировать на изменения в этом элементе. Можно задать однонаправленную привязку, чтобы программа только выводила на экран результаты при изменении свойства объекта. Наконец, можно связать любые свойства объектов так, чтобы программа могла переместить элемент Silverlight по экрану при изменении свойств X и Y объекта игры.

Создание объекта для привязки

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

  • текст верхнего элемента TextBox;
  • текст нижнего элемента TextBox;
  • текст элемента TextBlock.

Можно создать класс AdderClass, имеющий следующую структуру:

public class AdderClass
{
    private int topValue;
    public int TopValue
    {
        get
        {
            return topValue;
        }
        set
        {
            topValue = value;
        }
    }

    private int bottomValue;
    public int BottomValue
    {
        get
        {
            return bottomValue;
        }
        set
        {
            bottomValue = value;
        }
    }

    public int AnswerValue
    {
        get
        {
            return topValue + bottomValue;
        }
    }
}

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

Добавление функций уведомления

Для того чтобы класс можно было связать с объектом Silverlight, в нём должен быть реализован интерфейс INotifyPropertyChanged:

public interface INotifyPropertyChanged
{
    //  Событие происходит при изменении значений свойства
    event PropertyChangedEventHandler PropertyChanged;
}

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

public event PropertyChangedEventHandler PropertyChanged;

Класс PropertyChangedEventHandler используется элементами Silverlight для управления сообщениями событий. Он описан в пространстве имён System.ComponentModel. Если компонент Silverlight нужно связать с каким-либо свойством класса, можно добавить к этому событию делегаты.

Класс AdderClass будет использовать этот делегат для того, чтобы сообщить об изменении одного из свойств в классе. При этом произойдёт обновление экрана. Связанные с этими свойствами объекты Silverlight связываются с делегатом, чтобы они могли получить уведомление в случае необходимости. Окончательная версия класса может выглядеть так:

public class AdderClass : INotifyPropertyChanged
{
    public event PropertyChangedEventHandler PropertyChanged;

    private int topValue;

    public int TopValue
    {
        get
        {
            return topValue;
        }
        set
        {
            topValue = value;

            if (PropertyChanged != null)
            {
                PropertyChanged(this, new PropertyChangedEventArgs("AnswerValue"));
            }  
        }
    }

    // то же самое для свойства BottomValue
  
    public int AnswerValue
    {
        get
        {
            return topValue + bottomValue;
        }
    }  
}

Класс AdderClass теперь содержит свойство PropertyChanged. Каждый раз при изменении значения свойства он должен проверить значение свойства PropertyChanged. Если оно не равно null, то оно связано с делегатом. Можно рассматривать свойство PropertyChanged как список рассылки. Процесс может подписаться на рассылку и получать уведомления об интересующих событиях, которые происходят в AdderClass. Если никто не подписан на список рассылки (то есть значение PropertyChanged равно null), то нет точки вызова метода для описания изменений. Однако, если оно не равно null, это означает, что есть объект, который интересуют изменения, происходящие в AdderClass.

Вызов метода, который генерирует событие, выглядит следующим образом:

PropertyChanged(this, new PropertyChangedEventArgs("AnswerValue"));

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

Когда программа сгенерирует событие, на экран будет выведено обновлённое значение свойства AnswerValue. При вызове кода секции get свойства AnswerValue он вычисляет и возвращает результат.

public int AnswerValue
{
    get
    {
        return topValue + bottomValue;
    }
}

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

Добавление пространства имён на страницу MainPage

Для того чтобы связать созданный объект с данными, нужно связать код объекта с XAML-кодом, описывающим пользовательский интерфейс. Необходимо добавить в код XAML пространство имён, содержащее класс AdderClass:

xmlns:local="clr-namespace:AddingMachine"

Этот атрибут корневого элемента в XAML-файле для страницы MainPage.xaml делает доступными любые классы пространства имён AddingMachine для использования в XAML-коде. Как и в программе на C# в начале файла должны указываться все директивы using, так и в начале файла XAML также должны указываться все используемые пространства имён.

После добавления пространства имён нужно объявить имя класса, который описан в этом пространстве имён и используется в качестве ресурса:

<phone:PhoneApplicationPage.Resources>
  <local:AdderClass x:Key="AdderClass" />
</phone:PhoneApplicationPage.Resources>

Добавление класса к элементу на странице

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

<Grid x:Name="LayoutRoot" Background="Transparent"
    DataContext="{StaticResource AdderClass}">

Этот код указывает элементу Grid использовать класс AdderClass, указанный в значении атрибута DataContext. В нашем приложении он является статическим ресурсом, в котором класс является частью программы.

Привязка элемента Silverlight к свойству объекта

Теперь класс AdderClass доступен в контексте данных элементам на странице. При этом создаётся связь между страницей Silverlight и объектом, в котором описано поведение.

Теперь нужно привязать свойства каждого элемента к свойствам объекта. Для этого можно использовать область свойств для каждого элемента. Нужно связать текст элемента firstNumberTextBox со свойством TopValue класса AdderClass. Если щёлкнуть по элементу TextBox в редакторе Visual Studio, откроется область свойств для этого элемента, в которой для свойства Text в контекстном меню нужно выбрать пункт Применить привязку данных…. После этого откроется окно, в котором нужно указать, с каким свойством какого объекта требуется связать выбранное свойство элемента.

Выбрав необходимый элемент из списка доступных элементов и их свойств, можно привязать свойство элемента Silverlight к свойству объекта. Обратите внимание, что в разделе Параметры выбран режим TwoWay, при котором при изменении пользователем значения в элементе TextBox объект автоматически был об этом уведомлён.

При связывании с элементом TextBlock доступен только режим OneWay, поскольку нельзя передать в программу данные из объекта TextBlock.

После установки привязки программа будет работать. При этом содержимое файла MainPage.xaml.cs с кодом программы не изменится. Вся работа теперь выполняется в классе, который соединён с визуальными элементами. Изменение содержимого элементов TextBox, используемых для ввода значений, приведёт к возникновению события класса AdderClass, которые приведут к изменению содержимого класса AnswerValue, связанного с элементом ResultTextBlock.

Привязка данных через свойство DataContext

Для установки привязки к данным потребовалось проделать большую работу. Однако, существует способ упростить выполнение этих действий.

Можно просто связать свойство объекта со свойством элемента в XAML-коде, и Silverlight выполнит привязку.

<TextBox Height="72" HorizontalAlignment="Left" Margin="8,19,0,0"
    Name="firstNumberTextBox" Text="{Binding TopValue, Mode=TwoWay}"
    VerticalAlignment="Top" Width="460" TextAlignment="Center" />

В этом коде указана привязка текста элемента к свойству TopValue объекта. Режим привязки установлен в значение TwoWay, чтобы изменения в программе (при вычислении результата) отображались на экране. Если нужно использовать визуальный элемент только для того, чтобы показать значение (например, результат вычисления), можно использовать режим привязки OneWay.

Теперь остаётся создать экземпляр класса AdderClass и присвоить его свойству DataContext элемента, содержащего элемент firstNumberTextbox. Это можно сделать в конструкторе для основной страницы.

// Конструктор
public MainPage()
{
    InitializeComponent();

    AdderClass adder = new AdderClass();
    ContentGrid.DataContext = adder;
}

Свойство DataContext элемента Silverlight идентифицирует объект, который содержит все свойства, связанные с элементом и с теми элементами, которые в нём содержатся. Элемент ContentGrid содержит элементы TextBox и TextBlock, и теперь каждая привязка, которую эти элементы содержат, будет отображаться на созданный экземпляр класса AdderClass.

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

Сайт MSDN: http://msdn.microsoft.com/ru-ru/library/ms752347.

Задание к работе

  1. Откройте в Visual Studio созданный в предыдущих работах проект программы для Windows Phone.
  2. Создайте класс, который будет использоваться для привязки данных к визуальным элементам Silverlight вашего приложения.Определите необходимые свойства класса и перенесите код для вычисления результатов в методы созданного класса.
  3. Добавьте описание привязки свойств класса к визуальных элементам на странице приложения.
  4. Запустите программу и проверьте правильность её работы.
  5. Составьте отчёт о проделанной работе. Включите в отчёт необходимые листинги программы.