如何创建级联下拉列表

[原文发表地址]   Creating Cascading Drop Down Lists in Visual Studio LightSwitch

[原文发表时间] 2012-01-12 10:15 AM

在数据输入屏幕上常用的技术是使用一个"下拉列表"(在LightSwitch中称为自动完成框)作为下一步骤的筛选器。这限制了选择的数量,用户在指导下能更轻松地定位那些值。如果你已有一个级联筛选器的列表,第一个列表的选择可以在第二个列表中筛选数据,第二个列表的选择也在下一个列表中筛选数据,以此类推,这种情况下此时这个技术也很有用。LightSwitch通过使用参数化的查询和参数绑定可以轻易实现以上功能,在这篇文章中让我们来看看几种常见的情况。

基于多个表的级联列表

让我们看一个示例,这儿有一个关于国家的表以及它的子表城市表。当将客户输入系统时,城市是从客户表中选择出来的。因此我们在国家与城市以及城市与客户表之间存在一对多的关系。我们的数据模型如下所示:

image

当用户输入新的客户时,我们不希望在下拉列表中显示数千个城市。虽然用户可以使用自动完成框功能来查找一个城市,要读出并显示所有的城市也会影响性能。最好使用一个模式窗口选取器搜索对话框 (像我在这篇文章展示的),或者首先显示国家列表,然后基于该部分筛选城市列表。

首先,我们需要创建几个查询。第一个是简单地对国家列表进行排序,让它们在列表中以字母顺序显示。右键单击解决方案资源管理器中的国家表,添加一个查询以打开查询设计器。创建一个以国家名字升序排列的名为“SortedStates”的查询:

image

接下来,通过右击解决方案资源管理器中的城市表,再次选择添加查询来创建一个称为"CitiesByState"的查询。这一次我们将创建一个参数化的查询:Where State.Id属性等于一个称为Id新参数。查询设计器现在应该如下所示:

image

现在,像平常一样创建一个客户详细信息屏幕。右击Screens节点并选择"添加屏幕",选择编辑详细信息屏幕模板,然后为屏幕数据选择客户表。屏幕设计器将被打开,而且客户实体中的所有字段都将在内容树中。城市字段显示为自动完成框。

image

下一步,我们需要将数据项添加到我们的屏幕中,用于跟踪所选的国家。我们将使用此值来决定城市列表上的筛选器,以便用户只看到所选国家中的城市。单击"添加数据项目",并添加称为 SelectedState 的国家类型的本地属性。

image

下一步, 拖动SelectedState到内容树中的City上面。LightSwitch 将自动为你创建一个自动完成框控件。

image

因为我们想要以排序方式显示国家, 那么下一步将 SortedStates 查询添加到屏幕中。再次单击"添加数据项目",这次选择查询,然后选择 SortedStates。

image

接下来选择内容树中的 SelectedState 自动完成框,并在属性窗口中,将Choices属性设置为 SortedStates。

image

接下来,向屏幕中添加 CitiesByState 查询,并将城市自动完成框中的Choices属性设置为这个查询。再次单击"添加数据项目",然后选择 CitiesByState 查询。

image

然后选择城市自动完成框,将Choices属性设置为该查询。

image

最后,我们需要挂钩参数绑定。选择CitiesByState 查询的Id参数,然后在属性窗口中设置Parameter Binding为 SelectedState.Id。一旦你这样做了,左侧的灰色箭头将指示绑定成功。

image

一旦你设置查询参数的值,LightSwitch 将自动执行查询,因此你不需要为此编写任何代码。按下 f5 键,看看你工作的成果。请注意,城市下拉列表是空的,直到你选择一个国家,此时它激活CitiesByState 查询并执行它。此外请注意如果你选择了城市,然后更改国家,它会仍然正确显示所选内容,不会消失。只要记住当用户更改国家选择时,城市查询会针对服务器再次执行。

image

另一件你可能要做的事情是初始化显示这个城市属于哪个国家。当屏幕打开时,选定国家是空白的。这是因为它绑定到一个没有数据的屏幕属性。但是我们可以轻易地在代码中设置SelectedState 的初始值。回到屏幕设计器右上方下拉列表中的"编写代码"按钮,选择 InitializeDataWorkspace 方法,并编写下面的代码:

Private Sub CustomerDetail_InitializeDataWorkspace(saveChangesTo As List(Of Microsoft.LightSwitch.IDataService))

' Write your code here.

If Me.Customer.City IsNot Nothing Then

Me.SelectedState = Me.Customer.City.State

End If

End Sub

现在当你再次运行屏幕时,将显示选定的国家。

基于单个表的级联列表

另一个选择是创建基于单个表的级联列表。例如说我们根本没有国家表。相反,在城市表中存储国家会更有意义。所以,我们的数据模型可以简化为只有一个与多个客户相关的城市表

image

这次当我们创建一个名为 CitesByState的参数化查询时,我们会将它设置为:国家等于一个称为State新参数。

image

在屏幕上,选择"添加数据项目"来将 CitiesByState 添加到屏幕中,并将其设置为城市自动完成框的Choices属性,就像之前一样。

image

但是,这一次State是我们需要绑定的查询参数。添加字符串屏幕属性到屏幕中以保存选中的国家。再次单击"添加数据项目",添加所需类型字符串的本地属性,并将其命名为 SelectedState。

image

拖动SelectedState到内容树中City的上方。这次 LightSwitch 将创建一个文本框,因为这只是本地字符串属性。

image

最后,我们需要设置查询参数绑定。选择国家查询参数,然后在属性窗口中设置参数绑定为 SelectedState。

image

当打开屏幕时,为了设置 SelectedState,编写与之前相同的代码。现在当我们运行它时,你将看到一个文本框,用于筛选列表中的城市。

image

但是,这可能不完全是我们想要的。如果用户有一个自由格式的文本字段,则他们可能误键入国家代码,查询会返回没有结果。最好像之前一样,在自动完成框中显示国家。关闭应用程序,并再次打开屏幕设计器。选择 SelectedState 屏幕的属性。注意在属性窗口中你可以通过创建一个Choice列表来显示一个静态的值列表。

image

输入用户可以从中选择的国家,然后再次运行应用程序。现在,我们得到一个如之前的自动完成框。然而,这种方法让我们不得不在每个我们希望使用此功能的屏幕上定义国家的Choice列表。使用国家表的第一种方法可以解决这一问题,但我们也可以采取另一种方法来避免创建一个单独的表。

针对实体使用Choice列表

我们可以通过在客户实体上定义国家的Choice列表来改善这种情况。然后我们将只需在一个位置定义国家列表。在客户表中使用数据设计器创建一个State属性,并在属性窗口选择Choice列表,在那里指定国家的列表。

image

现在为客户表添加一个新的详细信息屏幕,你将看到国家和城市属性设置成了自动完成框。下一步和之前一样,单击"添加数据项目"来向屏幕添加 CitiesByState 查询。我们可以使用前面示例中的CitiesByState 查询。选择城市自动完成框,并和之前一样在属性窗口中设置Choices属性为 CitiesByState。

不同之处为查询参数绑定。选择左边的State查询参数,并在属性窗口中为Customer.State设置参数绑定。

image

使用此技术时,你也不需要编写任何代码来设置选定的国家初始值,因为我们在客户记录上存储该值。再次运行此应用程序,屏幕应该与之前一样运行。现在,唯一的区别是我们在客户表中存储国家,而不是把国家存在一个单独的表中。

image

这项技术上手最简单,所以如果你有大量的客户屏幕,而且你有像国家一样的值的静态列表,这可能是你的最佳选择。不过如果你有值的动态列表,那么你最好像第一个技术中展示的那样,将值存储在单独的表中。

关于筛选数据和配置列表的详细信息,请参阅:

希望大家喜欢!