|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
Announcements
Chapters
Services
Feature Zones
|
Note: This is an unedited contribution. If this article is inappropriate,
needs attention or copies someone else's work without reference then please
Report This Article
The problemHow many times where you required to let user select some data from the database? This means allowing the user to check some ticks on the data from the database and then to perform some actions based on the selected items. In ASP.NET 2.0 there are two controls that could do the trick: Another issue is the fact that I do not have a way of choosing how the elements will be displayed. If I want, at some point to change the way elements get selected from a multiple selection to a single selection, then you need to remove the What if you need to preselect some of the elements in the list you are displaying? The regular way would be to investigate each element as it comes from the database and setting the This are the problems I am addressing with this article. Goals:
A little backgroundIn a selection dialog we usually want to be able to display some text to the user and when the user selects that text to have a way of associating the text with a more meaningful element from the data, say the primary key of the selected element. So, besides showing the text to the user we must also keep the data that the element represents. This is what happens in ASP.NET also. For a ComboBox you have a Lets say we have some data that you need to display to the user and allow them to select some items from it. You could pass in a We need this dual approach because, setting the The IdeaThe idea is to use the existing controls from ASP.NET and add some extra functionality to them. For example, we could use the For instance, a SolutionWhen stated this problem, the solution becomes clear very quickly. We get a There is only one catch here: we need to store two pieces of information in a
The problem is that, by design, a I have seen this practice and I am not comfortable with it. The reason is that, in order to retrieve the value from the control we must resort to some string manipulation. Moreover, the value is available in clear text in the page source and thus it is vulnerable to change. Imagine that someone would use as a value the Credit Card number of a user. That data would be available in Clear Text to anybody!!! So we need to find a way of not showing the Fortunately, this is not such a big problem. Because a internal class CheckBoxWithValue : System.Web.UI.WebControls.CheckBox { private object myValue; /// <summary> /// This property will be used to store the associated Value /// </summary> public object Value { get { return myValue; } set { myValue = value; } } } The What do we gain by doing this? Well, besides the fact that now there is room to store the associated value in the control, the value is also encrypted. The encryption is part of the ASP.NET ViewState mechanism. The ViewState will encrypt all data regarding the controls on the form and this includes our controls ,thus the data will not be available to an attacker. Furthermore, ASP.NET will detect any change to the ViewState and report it to the user. More information regarding the ViewState you can find here. Now that we have this class, we can use it in order to create the list of controls. The code that builds the list of controls is shown below: 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/>")); } You can see that we add the RadioButtons to a single group of elements. We do this so we can benefit from the auto-deselect of other items when we select a new one. The control also provides the mean of retrieving the selected elements in the list. For this, we look at each control that was added and check it’s 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(); This function is actually a get accesor for the property SelectedItems of the control. This property adheres to the design pattern of other controls that expose this functionalityty (i.e. WinForms ListBox). We also can provide the control with an 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; } } else if (myControl.GetType() == typeof(CheckBoxWithValue)) { CheckBoxWithValue myButt = (CheckBoxWithValue)myControl; foreach (object o in values) { if (myButt.Value.ToString() == o.ToString()) myButt.Checked = true; } } } And with this function, the functionality of the control is complete. You can find the source code to the control at the top of this article, along with a sample web site that uses it. Read more to see how can you use this control. Using the controlBecause the OptionsControl is implemented as a There are a few properties that need to be set on the control before it can be used. Below you will find a table of the properties, it’s role and a suggested value.
For a demonstration of this control please refer to the top of the article where you will find both the control and a web site that utilizes the control. ConclusionIn this article I have described the way to build a user control that allows single and multiple selection of elements from a The control created follows the goals set in the introduction and can be used in ASP.NET web applications in order to display a selection of items to users and allow them to choose from them. Hopefully you enjoyed the read and you will use this control is you applications. Happy coding!
|
|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||