Главная » Silverlight » Извещение об изменении

0

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

Product product = (Product)gridProductDetails.DataContext; product.UnitCost *= 1.1;

Совет. Если планируется часто изменять связанный объект, не обязательно каждый раз извлекать его из свойства DataContext. Лучше сохранить его в поле на странице. Это упрощает код и уменьшает количество операций приведения типа.

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

Для решения проблемы класс данных должен реализовать интерфейс System. ComponentModel. INotifyPropertyChanged, определяющий единственное событие PropertyChanged. Когда свойство объекта данных изменяется, нужно сгенерировать со­бытие PropertyChanged и предоставить имя свойства в качестве строки.

Ниже приведено определение модифицированного класса Product, в котором исполь­зуются интерфейс INotifyPropertyChanged и код обработки события PropertyChanged.

public class Product : INotifyPropertyChanged

?• {

public event PropertyChangedEventHandler PropertyChanged;

public void OnPropertyChanged(PropertyChangedEventArgs e) {

if (PropertyChanged != null) PropertyChanged(this, e);

}

}

Событие PropertyChanged нужно генерировать во всех процедурах установки свойств.

private double unitCost;

public double UnitCost {

get { return unitCost; } set {

unitCost = value; OnPropertyChanged(new PropertyChangedEventArgs("UnitCost"));

}

)

При использовании данной версии класса Product в предыдущем примере будет реа­лизовано ожидаемое поведение. При изменении текущего объекта Product новая ин­формация немедленно появится в связанном текстовом поле.

Совет. Если изменяется несколько значений, можно вызвать метод OnPropertyChanged () и передать ему пустую строку. Она сообщит Silverlight о необходимости повторно вычислить выражения связывания, подключенные ко всем свойствам класса.

Создание службы данных

В представленных выше примерах рассмотрены все базовые компоненты связывания данных в Silverlight, однако они не очень реалистичные. В типичных реальных приложе­ниях данные извлекаются из внешних источников, таких как веб-службы. Тем не менее отличия между рассмотренными примерами и реальными приложениями минимальные. Осталось лишь рассмотреть привязку к коллекциям. Ведь на практике необходимо из­влекать информацию из баз данных, а не создавать сотни объектов Product в коде.

В дальнейших примерах используется простая служба данных, возвращающая объ­екты Product. В главе 15 рассматривалось создание и применение служб WCF. Службы данных создаются аналогично.

Первый этап состоит в перемещении класса объекта данных на сайт ASP.NET. Файл, содержащий код, нужно расположить в папке App_Code. Необходимо также немного из­менить объект данных: добавить в него атрибуты DataContract и DataMember, чтобы обеспечить его сериализацию.

[DataContract() ]

public class Product : INotifyPropertyChanged

{

private string modelNumber;

[DataMember ()]

public string ModelNumber

get { return modelNumber; }

set

{

modelNumber = value; OnPropertyChanged(new

PropertyChangedEventArgs("ModelNumber"));

} <*

}

private string modelName;

[DataMeoberO]

public string ModelName {

get { return modelName; )

set

{

modelName = value; OnPropertyChanged(new PropertyChangedEventArgs("ModelName"));

}

}

public Product(){}

}

Примечание. Интерфейс iNotif yPropertyChanged можно использовать для извещения об изменениях свойств, даже если объект данных определен в службе. При добавлении в приложение Silverlight ссылки на службу программа Visual Studio создает на стороне клиента копию класса Product, содержащую открытые члены и вызывающую метод OnPropertyChanged ().

После определения объекта данных нужно создать метод веб-службы, в котором он используется. Класс веб-службы предоставляет единственный метод, позволяющий вы­зывающему коду извлекать одну запись о продукте.

[ServiceContract(Namespace = "")]

[AspNetCompatibilityRequirements(RequirementsMode = AspNetCompatibilityRequirementsMode.Allowed)]

public class StoreDb {

private string connectionString = WebConfigurationManager.

AppSettings["storeDbConnectionString"] ;

[OperationContract()]

public Product GetProduct(int ID) < ‘

}

}

Запрос выполняется с помощью хранимой процедуры GetProduct базы данных. Чтобы строка соединения не была жестко закодированной, она извлекается из файла web.config, содержащего конфигурационные параметры приложения. Ниже приведен пример определения строки соединения в файле web. conf ig.

<configuration> <appSettings>

<add key="storeDbConnectionString"

value="Data Source=localhost;Initial Catalog=Store;^ Integrated Security=True" /> </appSettings>

</configuration>

Компонент базы данных, используемой в следующем примере, может извлекать та­блицу с информацией о продуктах из базы данных Store. Это учебная база данных, по­ставляемая в дистрибутивах программных продуктов Microsoft. Для ее устанрвки нужно выполнить сценарий store. sql, приведенный в примерах главы. Можно также исполь­зовать альтернативную версию, извлекающую эту же информацию из файла store. xml[7].

В книге внимание сосредоточено на связывании объектов данных с элементами Silverlight. Фактический процесс создания и заполнения объектов данных рассматрива­ется менее подробно (как и другие детали реализации приложения, такие как использова­ние кеша StoreDb в разных методах службы, применение хранимых процедур, выполнение встроенных запросов и т.д.). Тем не менее, чтобы вы получили представление о соедине­нии с базой данных, ниже приведен и кратко обсуждается полный код службы данных.

[ServiceContract(Namespace = "")]

[AspNetCompatibilityRequirements(RequirementsMode = AspNetCompatibilityRequirementsMode.Allowed)]

public class StoreDb {

private string connectionString = WebConfigurationManager. AppSettings["storeDbConnectionString"];

[OperationContract()]

public Product GetProduct(int ID)

{‘????

SqlConnection con = new SqlConnection(connectionString) ; SqlCommand cmd = new SqlCommandC’GetProductBylD", con) ; cmd.CommandType = CommandType.StoredProcedure; cmd.Parameters.AddWithValue("@ProductID", ID) ;

try                                                                                                                        „

{

con.Open ();

SqlDataReader reader =

cmd.ExecuteReader(CommandBehavior.SingleRow);

if (reader.Read())

{

// Создание объекта Product, служащего оболочкой // текущей записи Product product = new

Product((string)reader["ModelNumber"], (string)reader["ModelName"], Convert.ToDouble(reader["UnitCost"]), (string)reader["Description"]); return product;

)

else

return null;

}

}

finally <

con.Close () ;

}

}

}

Примечание. В методе GetProduct О , используемом в примере, нет кода обработки исключений. Поэтому исключения поднимаются вверх по иерархии вызывающего кода. На практике часто так и делают, однако в некоторых ситуациях лучше перехватить исключение в методе GetProduct (). Тогда можно будет выполнить очистку или запись в журнал, а затем вновь сгенерировать исключение, чтобы известить вызывающий код о проблеме.

Непосредственное использование объектов ADO.NET (как в данном примере) — наи­более простой и чистый способ кодирования службы данных. Отсоединенные объекты ADO.NET, такие как DataSet, в Silverlight используются редко, потому что в Silverlight нет встроенных классов, позволяющих манипулировать ими.

Источник: Мак-Дональд, Мэтью. Silverlight 3 с примерами на С# для профессионалов. : Пер. с англ. —- М. : ООО «И.Д. Вильяме», 2010. — 656 с. : ил. — Парал. тит. англ.

По теме:

  • Комментарии