如何生成允许单个或者多个项选择的网页用户控件

分享于 

14分钟阅读

Web开发

  繁體

示例图像- selectitemscontrol.jpg

问题

你需要用户从数据库中选择某些数据的次数? 这意味着允许用户检查数据库中的数据,然后根据所选项执行一些操作。

在 ASP.NET 2.0中,有两个控件可以实现以下功能: CheckBoxListRadioButtonList。这些控件允许你将 DataSource 属性设置为它们,并且它们将处理所有的工作。 但是,如果需要获取列表中的选定项,则必须手工执行,如果选中了每个元素,则检查每个元素。 这不是错误的方法,它只是错误的一个,因为你必须重新编写相同的代码。

另一个问题是,我没有选择如何显示元素的方法。 在某一时刻,要改变元素从多选择选择的方式,我需要删除 CheckBoxList,添加 RadioButtonList,然后( re ) 编写必要的逻辑使它的工作。 这是一个大的生产力问题,因为不能更改单个属性,需要从头( 几乎) 重新创建它。

如果需要预选显示的列表中的某些元素,请执行下列操作:? 常规方法是在数据库中对每个元素进行调查,并在绑定项上设置 Selected 属性。 如果你只能将要选择的元素的array 传递给控件并使它的执行所有工作,将不会很好?

这是我在本文中讨论的问题。

目标:

  • 我希望有一个可以让我显示用户选择的控件。
  • 要更改单个选择( 例如,RadioButton )的显示方法,请更改单个属性的显示方式。
  • 我希望能够从控件中检索选定项的列表。
  • 我希望能够通过传入所选元素的array 来预选列表中的某些项。

A 背景

在选择对话框中,我们通常希望能够向用户显示一些文本,当用户选择文本的时候。

因此,除了向用户显示文本之外,还必须保留元素所代表的数据。 在 ASP.NET 中也会这样。 对于 ComboBox,你有一个 SelectedText 和一个 SelectedValueSelectedText 是显示给用户的文本,SelectedValue 是该文本的有意义的值( 数据库智能)。

假设我们有一些数据,我们需要显示给用户,并允许它们从中选择一些项目。 如果你传入 DataTable 并指定哪个列是显示列,那么你可以直接传入连接字符串,或者你只需要传递一个连接字符串和一个SQL查询,就可以从数据库中获取数据。 这里控件将同时支持两种方案。

我们需要这种双方法,因为设置连接字符串和 SqlCommand 可以在设计中完成,而设置 DataTable 最有可以能。 由于连接字符串可以存储在 web.config 中,因此只需传递连接字符串所在的配置元素的NAME 即可。

这个想法

它的思想是使用 ASP.NET 中的现有控件,并为它们添加一些额外的功能。 例如可以使用 CheckBox 控件在多选择列表中显示项,而在简单选择模式下,使用 RadioButton 显示元素。 这样,我们就可以重用现有代码及其功能。

例如当 RadioButton 被选中时,会取消选择组中的所有其他 RadioButton。 这是我们获得"免费"的一个非常有用的行为。

解决方案

当解决这个问题时,解决方案变得非常清晰。 我们得到一个 DataTable。对于 DataTable 中的每一行,我们必须创建相应的控件。 控件的类型将根据指定的选择模式来确定。 如果我们想要单个选择,我们将添加 RadioButton,如果需要多个选择,我们将添加 CheckBox

这里只有一个陷阱: 我们需要在 CheckBox ( 或者 RadioButton ) 控件中存储两个信息:

  • 文本- 表示显示给用户的部分。
  • 值- 与文本关联的相应值。 不应将此值显示给用户。

问题是,通过设计,CheckBox 或者 RadioButton 只有存储它的中一个的空间,在名为 Text的属性中。 当然,可以选择将关联值嵌入控件( 标识用于唯一标识页上的控件)的ID。

我看到过这种实践,我对它不太适应。 原因是,为了从控件中检索值,我们必须采取一些字符串操作。 此外,该值在页源中以明文形式提供,因此很容易更改。 想象一下有人使用一个用户的信用卡号码。 这些数据将以明文形式提供给任何人 !

所以我们需要找到一个不在明文中显示 Value的方法。

幸运的是,这不是一个大问题。 因为 CheckBox 是. NET 中的类,我们可以简单地从该类派生,并创建自己的CheckBox 并将它的命名为 CheckBoxWithValue。 在这里派生类中,我们可以声明一个属性 Value,它可以包含控件的关联值。 因为我们从 CheckBox 类派生,所以我们得到的CheckBox的行为没有额外的费用。 我们现在可以使用派生控件,就像它是一个普通的CheckBox 一样。 它就像一个 CheckBox。 唯一的差别在于现在,我们有一种方法来存储 TextValue 一个控件。

internalclass CheckBoxWithValue : System.Web.UI.WebControls.CheckBox
{
 privateobject myValue;
 ///<summary>/// This property will be used to store the associated Value///</summary>publicobject Value
 {
 get { return myValue; }
 set { myValue = value; }
 }
}

Value 是作为一个 对象 为了在该属性中存储任何类型的对象,。

我们通过这样做得到了什么? 除了在控件中存储关联值的事实之外,该值也被加密了。 加密是 ASP.NET ViewState机制的一部分。 视图将对窗体上的控件加密所有数据,这包括我们的控件,因这里数据不可以用。 此外,ASP.NET 将检测到对ViewState的任何更改并向用户报告。 有关ViewState的更多信息,请参见这里。

现在我们有了这个类,我们可以使用它来创建控件列表。 生成控件列表的代码如下所示:

foreach (DataRow myRow in myData.Rows)
{
 Control myControl = null;
 switch (myOptionsType)
 {
 case OptionsSelect.Single:
 {
 RadioButtonWithValue myBut = new RadioButtonWithValue();
 myBut.Text = myRow[myDisplayField].ToString();
 myBut.Value = myRow[myValueField];
 myBut.ID = string.Format("{0}_{1}", "RadioButton", i++);
 myBut.GroupName = string.Format("GroupName{0}", this.ID);
 //We select one of the RadioButtons (the first one)if (i == 1)
 myBut.Checked = true;
 myControl = myBut;
 break;
 }
 case OptionsSelect.Multiple:
 {
 CheckBoxWithValue myCheck = new CheckBoxWithValue();
 myCheck.Text = myRow[myDisplayField].ToString();
 myCheck.ID = string.Format("{0}_{1}", "CheckBox", i++);
 myCheck.Value = myRow[myValueField];
 myControl = myCheck;
 break;
 }
 }
 ObjectsPanel.Controls.Add(myControl);
 ObjectsPanel.Controls.Add(new LiteralControl("<br/>"));
}

可以看到,我们将 RadioButton的元素添加到单个元素组中。 这样做可以在选择新项时从自动取消选择其他项中获益。

控件还提供检索列表中选定元素的方法。 为此,我们将查看添加的每个控件并检查它的Checked 属性。 如果设置了属性,那么我们将它的Value 添加到列表中。 在查看所有控件之后,返回列表。

List<object> myItems = new List<object>();switch (myOptionsType)
{
 case OptionsSelect.Single:
 {
 foreach (Control myControl in ObjectsPanel.Controls)
 {
 RadioButtonWithValue myRadio = null;
 if (myControl.GetType() == typeof(RadioButtonWithValue))
 {
 myRadio = (RadioButtonWithValue)myControl;
 if (myRadio.Checked == true)
 {
 myItems.Add(myRadio.Value);
 break;
 }
 }
 }
 break;
 }
 case OptionsSelect.Multiple:
 {
 foreach (Control myControl in ObjectsPanel.Controls)
 {
 CheckBoxWithValue myCheck = null;
 if (myControl.GetType() == typeof(CheckBoxWithValue))
 {
 myCheck = (CheckBoxWithValue)myControl;
 if (myCheck.Checked == true)
 {
 myItems.Add(myCheck.Value);
 }
 }
 }
 break;
 }
}return myItems.ToArray();

这个函数实际上是一个 获取 控件的属性 SelectedItems的accesor。 这里属性遵循公开这里功能(。例如,WinForms ListBox )的它的他控件的设计 Pattern。

我们还可以使用 InitialState 提供控件,通过传递表示要选择的元素的Value s的对象的array。

List<object> myItems = new List<object>();foreach (Control myControl in ObjectsPanel.Controls)
{
 if (myControl.GetType() == typeof(RadioButtonWithValue))
 {
 RadioButtonWithValue myButt = (RadioButtonWithValue)myControl;
 foreach (object o in values)
 {
 if (myButt.Value.ToString() == o.ToString())
 myButt.Checked = true;
 }
 }
 elseif (myControl.GetType() == typeof(CheckBoxWithValue))
 {
 CheckBoxWithValue myButt = (CheckBoxWithValue)myControl;
 foreach (object o in values)
 {
 if (myButt.Value.ToString() == o.ToString())
 myButt.Checked = true;
 }
 }
}

在这个函数中,控件的功能是完整的。 可以在本文的顶部找到控件的源代码,以及一个使用该控件的示例网站。 阅读更多内容,了解如何使用这里控件。

使用控件

由于 OptionsControl 是作为 UserControl 实现的,因此可以将它的拖动到从解决方案资源管理器拖放到页上的&。

在控件上需要设置一些属性,然后才能使用它。 下面,你将找到一个属性表。它的角色和建议值。

属性描述
Height控件的高度。 可以留空。
Width控件的宽度。 可以留空。
OptionsType

选择模式可用选项包括:

  • Single
  • Multiple
ConnectionString

用于连接数据库的连接字符串。 此值可以包含完全连接字符串或者来自 web.config的连接字符串的NAME,其中存储完整连接字符串。

这样可以在更多的地方使用相同的连接字符串。

CommandString应在数据库上运行以检索数据的SQL查询。 如果在控件上使用 DataTable 属性设置了数据,则此值可以为空。
CommandType要使用的命令的类型。 当 CommandString 中指定的文本是存储过程的NAME 时,必须设置为 StoredProcedure。 在指定SQL查询时,必须将这里属性设置为 Text
DisplayField数据库中包含由用户显示的文本的列的NAME。
ValueField数据库中包含将与文本关联的值的列的NAME。
DataTable用于显示控件而不是从数据库中检索数据的DataTable
InitialState包含必须检查的值的对象的array。 这里 array 应包含 ValueField 中指定的元素,而不包含 DisplayField 中指定的元素。

有关这里控件的演示,请参阅文章的顶部,你将在该文章中找到控件和使用控件的网站。

结束语

在本文中,我描述了构建用户控件的方法,该控件允许从 DataTable 中选择单个和多个元素。

所创建的控件可以在引用中的目标集中使用,可以在 ASP.NET web应用程序中使用,并允许他们选择。

希望你喜欢阅读,你将在你的应用程序中使用这个控件。

开心编码!


WEB  控制  构建  USE  用户  Select  
相关文章