Silverlight параллельные источники данных для управления сеткой

#c# #silverlight #silverlight-4.0 #wcf-ria-services

#c# #silverlight #silverlight-4.0 #wcf-ria-services

Вопрос:

У меня есть следующая модель данных:

Camp -> CampEvent <- Событие.

У Camp есть CampId и имя, связанное с ним. Событие имеет идентификатор события, имя, начало / конец (даты). CampEvent имеет (CampId,EventID)PK, CampId FK, EventID FK.

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

Я успешно могу отобразить таблицу событий в Silverlight, используя сетку.

В сетке есть два столбца шаблона — один для отображения флажка, а другой для отображения названия события.

Итак, теперь проблема в том, что мне каким-то образом нужно устанавливать флажки, когда этот элемент управления переходит в режим редактирования.

Я заметил, что у сетки нет события OnDataBound, или у нее нет способа установить состояние каждого флажка на checked, кроме как через привязку.

Ответ №1:

Ну, по-видимому, в Silverlight у вас нет роскоши возиться с содержимым GridViewRow. Однако вы можете добиться этого, изменив базовый источник данных.

В приведенном выше сценарии у нас есть элемент управления, который используется для создания экземпляра Camp и связывания его с одним или многими событиями. В некотором смысле элемент управления может либо создавать, либо обновлять объект «Camp» и его связи с событиями. Состояние элемента управления контролируется перечислением public enum Mode { Create, Update }; и в зависимости от того, какое значение имеет это свойство, элемент управления будет выполнять либо одну, либо обе из следующих операций привязки:

  1. Получить все данные о событиях и отобразить их в сетке, состоящей из строк, имеющих флажок и метку.
  2. Установите флажки, обозначающие события, в которых участвует конкретный лагерь.

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

Итак, для достижения моей цели я предпринял следующие шаги.

  1. Объявите ObservableCollection, где T используется только для привязки. В этом случае базовым источником данных для T является наше событие, а запрос Linq to Entity использовался для получения идентификатора и имени события и преобразования его в объект CampEvent с его свойством IsChecked, для которого по умолчанию установлено значение false.

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

  3. Ну, номер 2 был неправильным, поэтому элемент управления находился в режиме «Обновления». Если свойство SelectedCamp элемента управления установлено (и это свойство имеет тип Camp). На этом этапе мы создаем запрос Linq к объектам, в котором мы просим доменную службу включить события, связанные с указанным лагерем.

  4. Как только приходит ответ от запроса, мы выполняем итерацию по каждому объекту события, который связан с camp. Для каждого полученного события мы проверяем, существует ли оно в нашем источнике данных ObservableCollection. Если это происходит, мы устанавливаем для свойства IsChecked значение true для этого элемента. Как только мы привяжем сетку к данным, все события, связанные с конкретным лагерем, будут «проверены».

  5. Миссия выполнена.

Несколько слов о структуре базы данных, моделях предметной области, сгенерированных Entity Framework, и WCF RIA.

Что ж, как оказалось, EF предоставит вам, возможно, 80% из коробки. Инструмент недостаточно умен, чтобы знать, что такое отношение «многие ко многим». В случае с camp и events мы имеем следующую структуру:

 camp -> participates in many -> events
(many) events -> have many -> camps (as participants)
  

Итак, чтобы это произошло, нам нужна таблица «joiner» между лагерями и событиями. Чтобы сделать это правильно, в таблице joiner теоретически должно быть как минимум два столбца:

CampId -> EventID внешнего ключа -> Внешний ключ

Теперь, чтобы создать первичный ключ для таблицы, мы должны иметь:

CampId EventID -> Составной первичный ключ.

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

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

** 1. Найдите информацию о метаданных лагеря. Украсьте IEnumerble<Event>Events свойство:

 [Include]
[Association("CampEvent", "CampId", "EventId", IsForeignKey=True)]
  

И объяснить, что это значит: В Include говорится, что всякий раз, когда вы запрашиваете модель предметной области, пожалуйста, включайте каждое событие для указанного лагеря (ов). В ассоциации говорится, что существует таблица ассоциаций между camp и event для работы свойства навигации. В таблице поиска у camp есть идентификатор CampId, а у события есть EventID. Используйте их, чтобы найти все события для указанного лагеря (ов) **.

2. Сделайте то же самое для любых других навигационных свойств, которые у вас есть.