|
-
Aug 4th, 2010, 01:12 PM
#1
Get edit control from type
Hi,
I am retrieving some records from a database dynamically, not knowing exactly which table I need to query, or even which fields to retrieve. I display this data in a control that looks a bit like a listbox, except each item is two lines: a label and a value.
Now, the user needs to be able to browse through this list until he finds the item he needs, and then he should be able to edit the item.
This application will (eventually, this is just a 'proof of concept') run on a mobile device or PDA or something like that, so space is limited. To allow the user to edit a value, I simply show a panel containing some edit control (textbox, checkboxes, combobox, etc), let the user edit whatever he's editing, save the change and display the list of items again.
The problem now is that the items I'm getting are completely dynamic. They are not known during design-time, and in fact most of them don't even exist yet. The application can display items from any simple database by simply providing it with the tablename and a list of attributes to retrieve. I could go out and create a new table right now, tell the application which attributes to show (also in the same database) and it would happily show them.
So, I cannot possibly know the type of the data I am getting, so I can also not know which kind of editing control I need to provide!
For example, if the data is of type String, I could display a Textbox. If the data is of type Color, I could display a color combobox. If the data is any kind of collection (IEnumerable maybe), I show a regular combobox.
Boolean - Checkbox
Integer - Numeric textbox (with only integer values)
Double/Single - Numeric textbox (with floating point values)
etc
etc...
The most straightforward way of doing this is of course just a very long Select Case statement:
vb.net Code:
Public Function GetEditingControl(ByVal data As Object) As Control Select Case data.GetType() Case GetType(String) Return New TextBox() Case GetType(Integer) Return New NumericTextBox() Case GetType(Boolean) Return New CheckBox() Case '... End Select End Function
Problems with this:
1. It's ugly, long code, hard to maintain and hard to change.
2. I am going to run into data once that I did not foresee. So I am going to need a 'Case Else' to catch those cases. What kind of control do I return then? A TextBox maybe? I dunno.
3. Probably more that I can't think of right now...
Does anyone know any better way to do this? The Framework itself does it too somehow: if you've ever used the designer ActionLists (the shortcut windows that pop up if you click the [>] button on the top-right corner of some controls) you would know. You simply provide the designer with a bunch of properties, and somehow it determines, from those properties alone (presumably their type) which kind of control to show. It can show comboboxes, textboxes, numeric textboxes, checkboxes, Font dropdowns, Color dropdowns, etc...
I am kind of doubtful that they use a Select Case statement... But I can't think what else they would use?
EDIT
I also thought of a Dictionary(Of Type, Control) or something, but except for being long and ugly this approach has the same problems...
-
Aug 4th, 2010, 01:28 PM
#2
Re: Get edit control from type
First of all, I think the Dictionary, even better a Hashtable is a good sollution. And it is not very difficult to get ALL types, they can be found in the System.Data.SqlTypes enum. Only some can't be edited (binary data like SqlBinary or SqlFileStream) but for the others you can "match" a control type
-
Aug 4th, 2010, 01:48 PM
#3
Re: Get edit control from type
Well, it's probably based on a tree. You have your base Control methods, and a list of methods that are not inherited from Control in the classes that inherit Control. You loop through all the properties. If Control does not contain one of these properties, look for a class that inherits from Control or a child of control that has that property and create it. This can all be done with Reflection. Finally, use (Windows Forms Assembly).CreateInstance() to create the type, modify its properties, and return it. Easy enough!
-
Aug 4th, 2010, 01:50 PM
#4
Re: Get edit control from type
It could be made simpler by having an array containing all of the types that could be created. That would make things a whole heck of a lot simpler, so I suggest you do that. Just check each one in turn (have them in order of complexity/specalization, so Control -> TextBox -> ComboBox -> Color ComboBox, etc.) for the properties.
-
Aug 4th, 2010, 01:59 PM
#5
Re: Get edit control from type
I don't see what properties and methods have got to do with it. Can you explain? You say "if the control does not contain one of these properties"... what are "these" properties?
-
Aug 4th, 2010, 02:03 PM
#6
Re: Get edit control from type
Pass in the DataColumn and use GetType(YourDataColumn) then you'll know what datatype it's holding.
Edit: The DataColumn has a 'DataType' property you can use as well.
Last edited by JuggaloBrotha; Aug 4th, 2010 at 02:06 PM.
-
Aug 4th, 2010, 02:05 PM
#7
Re: Get edit control from type
The properties entered. That's probably how MS did it. In this case, use reflection to get the object's properties.
-
Aug 4th, 2010, 03:19 PM
#8
Re: Get edit control from type
Ah, those properties. Still don't understand it though. Those properties are not properties of a Control. They can be anything you want. And in my case, the properties aren't even in a control, just in some class that holds database entries.
@JB: I know how to get the type of the data (even though I'm not using any DataColumns, just plain old SQL), I just don't know how to match up those types with the edit control that is 'intuitively' used to edit them.
-
Aug 4th, 2010, 03:22 PM
#9
Re: Get edit control from type
It can be modified to suit whatever need. Just look for properties specific to one type.
-
Aug 4th, 2010, 03:26 PM
#10
Re: Get edit control from type
Or, you could have everything implement an interface, so:
Code:
Public Interface IEditable
Function GetEditingControl() As Control
End Interface
-
Aug 4th, 2010, 03:52 PM
#11
Re: Get edit control from type
What I'd do is to have a table in a database (or something equivalent that you can easily edit outside of the program and more importantly, without having to change the source code). This table will have, let's say, 2 columns:
- TypeName: the name of the data type
- ControlName: the type name of the editing control to be used.
You then can use Activator.CreateInstance and pass in the type name of the editing control to be created.
So supposed you have this table
Code:
TypeName EditingControlTypeName
System.String System.Windows.Forms.TextBox
System.DateTime System.Windows.Forms.DateTimePicker
System.Boolean System.Windows.Forms.CheckBox
System.Integer Application1.NumericTextBox
And when you have the type of the data, you can look up in this table for that record and use Activator.CreateInstance(CStr(row.Item("EditingControlTypeName"))
Let us have faith that right makes might, and in that faith, let us, to the end, dare to do our duty as we understand it.
- Abraham Lincoln -
-
Aug 4th, 2010, 04:33 PM
#12
Re: Get edit control from type
Sorry guys, I was being stupid. Stanav, you made me see the solution by suggesting to store the types in the database... I can do much better actually. I already have a table in my database that stores the label and the data-field used to retrieve the data for every data item*. I can just as well extend that table and also store how to edit the data. I can even store much more details, such as how many checkboxes to use, where to retrieve the data to fill comboboxes, etc...
*Here's that table (example):

Basically, this tells my application where to place which details of the data. The DL_DETAILS_ID points to another table that holds the name of the table to retrieve the data from (as well as some other details) allowing me to construct an SQL query to retrieve it (without even knowing the table). The LIST_POSITION is simply a sort order. The DATA_LABEL is simply a label and the DATA_FIELD is the column name of the data to use in this position.
Sooo I guess this is resolved 
Thanks!
Posting Permissions
- You may not post new threads
- You may not post replies
- You may not post attachments
- You may not edit your posts
-
Forum Rules
|
Click Here to Expand Forum to Full Width
|