网格控件的 Silverlight 并发数据源
本文关键字:并发 数据源 Silverlight 控件 网格 | 更新日期: 2023-09-27 17:56:17
我有以下数据模型:
营地 -> 营地活动 <- 活动。
Camp具有与之关联的 CampId 和 Name。事件具有事件 ID、名称、开始/结束(日期)。CampEvent 有 (CampId,EventId)PK, CampId FK, EventId FK.
这些表用于创建域模型和域服务,这些模型和域服务在 Silverlight 上的客户端使用。
我能够使用网格在 Silverlight 中成功显示事件的表。
网格有两个模板列 - 一个用于显示复选框,另一个用于显示事件的名称。
所以现在的问题是,当此控件进入编辑模式时,我需要选中复选框。
我注意到网格没有 OnDataBound 事件,或者它无法将每个复选框的状态设置为选中,而不是通过绑定。
显然,在Silverlight中,你没有奢侈地弄乱GridViewRow的内容。但是,您可以通过更改基础数据源来实现此目的。
在上面的场景中,我们有一个控件,用于创建 Camp 的实例并将其与一个或多个事件相关联。从某种意义上说,控件可以创建或更新"Camp"对象及其与事件的关系。控件状态由枚举public enum Mode { Create, Update };
控制,根据此属性具有的值,控件将执行以下一个或两个绑定绑定操作:
- 获取所有事件数据并将其显示在由具有复选框和标签的行组成的网格中。
- 选中表示特定营地参与的活动的框。
这在理论上是很好和花花公子的,但原则上我意识到 Silverlight 需要一个离散的数据源来绑定。我创建了一个 CampEvent 自定义对象的集合,其中每个元素都有一个布尔值 prperty IsChecked,以及事件名称和事件 ID。CampEvent 对象不是域实体对象,仅用于绑定。
因此,为了实现我的目标,这些是我采取的步骤。
-
声明 ObservableCollection,其中 T 仅用于绑定。在本例中,T 的基础数据源是我们的事件,并且使用 Linq 到实体查询来获取事件的 ID 和名称,并将其转换为 CampEvent 对象,默认情况下其 IsChecked 属性设置为 false。
-
如果控件处于创建模式,我就完成了。网格的模板列中的复选框双向绑定到基础数据源的 IsChecked 属性。第一步足以创建未选中所有复选框的默认 UI。否则转到 3
-
好吧,数字 2 是错误的,因此控件处于"更新"模式。如果设置了控件的 SelectedCamp 属性(并且此属性的类型为 Camp)。此时,我们创建一个 Linq to Entitities 查询,在该查询中,我们要求域服务包含与指定阵营关联的事件。
-
查询响应到达后,我们将循环访问与营地关联的每个 Event 对象。对于收到的每个事件,我们检查它是否存在于我们的 ObservableCollection 数据源中。如果是这样,我们将该项的 IsChecked 属性设置为 true。一旦我们对网格进行数据绑定,与特定阵营关联的所有事件都将被"选中"。
-
任务完成。
关于数据库结构、实体框架生成的域模型和 WCF RIA 的几句话。
好吧,事实证明,EF 可能会让您开箱即用地获得 80%。该工具不够智能,无法知道什么是多对多关系。在营地和事件的情况下,我们有以下结构:
camp -> participates in many -> events
(many) events -> have many -> camps (as participants)
因此,为了实现这一目标,我们需要在营地和活动之间建立一个"加入者"表。为了正确地执行此操作,连接器表理论上至少应具有两列:
坎普迪 -> 外键事件 ID -> 外键
现在要为表创建一个主键,我们应该有:
CampId + EventId -> 复合主键。
使我们的表只有 2 个字段。现在,这非常重要,因为此关系在 EF 中创建可能的导航属性。
生成域模型时,EF 不会在模型中创建连接器表。但是,若要启用 Camp 和事件之间的导航属性,反之亦然,必须在基础域服务元数据对象上发生一些事情。
**1.找到营地元数据信息。装饰IEnumerble<Event>Events
物业:
[Include]
[Association("CampEvent", "CampId", "EventId", IsForeignKey=True)]
并解释这些含义:包含说每当您查询域模型时,请包含指定阵营的每个事件。该协会表示,营地和事件之间有一个关联表,以便导航属性正常工作。在查找表中,营地具有CampId标识符,事件具有EventId。使用它们查找指定营地的所有事件**。
2. 对你拥有的任何其他导航属性执行相同的操作。