Help needed with custom dynamic control.

N

NateDawg

I’ve got a question about dynamic controls and retrieving the data back after
the user enters information into them. Here is what I have so far.
I made a custom control for this as I will need to use it multiple times and
on many different pages. This control takes in a ListItemCollection and then
builds a table off of it with controls for each item in the collection. First
is a label the text is just the ListItem from the collection. Next is three
text boxes first is “header text†then “sort expression†then “data format
stringâ€. The last item is a check box for “visibleâ€. So far this is all
working, but I need to figure out A) Is there a better way to do what I’m
doing right now? B) How do I get the data back from the fields after a user
is done entering data into them? The ascx page is simply…

<%@ Control Language="VB" AutoEventWireup="false"
CodeFile="DynDetails.ascx.vb" Inherits="BRAssociates.Modules.DDIM.DynDetails"
%>
<asp:Table ID="Table" runat="server" />

I’ll admit the ascx.vb page is a hacky at this point, but here is the code.

Imports System

Namespace BRAssociates.Modules.DDIM
Public MustInherit Class DynDetails
Inherits Framework.UserControlBase

Private _FieldCollection As New
System.Web.UI.WebControls.ListItemCollection

Public Event Build_Grid(ByVal sender As Object, ByVal e As EventArgs)

Public Property Fields() As
System.Web.UI.WebControls.ListItemCollection
Get
Fields = _FieldCollection
End Get
Set(ByVal Value As System.Web.UI.WebControls.ListItemCollection)
_FieldCollection.Clear()
_FieldCollection = Value
End Set
End Property

Public Sub Raise_Build_Grid(ByVal sender As Object, ByVal e As
EventArgs)
RaiseEvent Build_Grid(sender, e)
End Sub

Private Sub Page_Load(ByVal sender As System.Object, ByVal e As
System.EventArgs) Handles MyBase.Load
Table.CssClass = "table"

Dim row As New System.Web.UI.WebControls.TableRow

Dim plDataField As New System.Web.UI.WebControls.Label
plDataField.Text = "Data Field"
plDataField.CssClass = "Head"

Dim cDataField As New System.Web.UI.WebControls.TableCell
cDataField.Controls.Add(plDataField)

row.Cells.Add(cDataField)

Dim plHeaderText As New System.Web.UI.WebControls.Label
plHeaderText.Text = "Header Text"
plHeaderText.CssClass = "Head"

Dim cHeaderText As New System.Web.UI.WebControls.TableCell
cHeaderText.Controls.Add(plHeaderText)

row.Cells.Add(cHeaderText)

Dim plSortExpression As New System.Web.UI.WebControls.Label
plSortExpression.Text = "Sort Expression"
plSortExpression.CssClass = "Head"

Dim cSortExpression As New System.Web.UI.WebControls.TableCell
cSortExpression.Controls.Add(plSortExpression)

row.Cells.Add(cSortExpression)

Dim plDataFormatString As New System.Web.UI.WebControls.Label
plDataFormatString.Text = "Data Format String"
plDataFormatString.CssClass = "Head"

Dim cDataFormatString As New System.Web.UI.WebControls.TableCell
cDataFormatString.Controls.Add(plDataFormatString)

row.Cells.Add(cDataFormatString)

Dim plVisible As New System.Web.UI.WebControls.Label
plVisible.Text = "Visible"
plVisible.CssClass = "Head"

Dim cVisible As New System.Web.UI.WebControls.TableCell
cVisible.Controls.Add(plVisible)

row.Cells.Add(cVisible)

Table.Rows.Add(row)

RaiseEvent Build_Grid(sender, e)
End Sub

Private Sub Build_DataFields(ByVal sender As System.Object, ByVal e
As System.EventArgs) Handles Me.Build_Grid
Dim objListItem As New System.Web.UI.WebControls.ListItem

For Each objListItem In _FieldCollection
Dim row As New System.Web.UI.WebControls.TableRow

Dim plDataField As New System.Web.UI.WebControls.Label
plDataField.Text = objListItem.ToString()
plDataField.CssClass = "SubHead"

Dim cDataField As New System.Web.UI.WebControls.TableCell
cDataField.Controls.Add(plDataField)

row.Cells.Add(cDataField)

Dim tbHeaderText As New System.Web.UI.WebControls.TextBox
tbHeaderText.Text = objListItem.ToString()
tbHeaderText.ID = "ht" & objListItem.ToString()
tbHeaderText.CssClass = "NormalTextBox"

Dim cHeaderText As New System.Web.UI.WebControls.TableCell
cHeaderText.Controls.Add(tbHeaderText)

row.Cells.Add(cHeaderText)

Dim tbSortExpression As New System.Web.UI.WebControls.TextBox
tbSortExpression.Text = objListItem.ToString()
tbSortExpression.ID = "se" & objListItem.ToString()
tbSortExpression.CssClass = "NormalTextBox"

Dim cSortExpression As New System.Web.UI.WebControls.TableCell
cSortExpression.Controls.Add(tbSortExpression)

row.Cells.Add(cSortExpression)

Dim tbDataFormatString As New
System.Web.UI.WebControls.TextBox
tbDataFormatString.ID = "dfs" & objListItem.ToString()
tbDataFormatString.CssClass = "NormalTextBox"

Dim cDataFormatString As New
System.Web.UI.WebControls.TableCell
cDataFormatString.Controls.Add(tbDataFormatString)

row.Cells.Add(cDataFormatString)

Dim cbVisible As New System.Web.UI.WebControls.CheckBox
cbVisible.ID = "cb" & objListItem.ToString()

Dim cVisible As New System.Web.UI.WebControls.TableCell
cVisible.Controls.Add(cbVisible)

row.Cells.Add(cVisible)

Table.Rows.Add(row)
Next
End Sub
End Class
End Namespace

Now, I’m sure anyone reading this is wondering why I used event firing to
build the dynamic portion of this control. Well, the ListItemCollection comes
from a custom dual list box control. And this control will need to change
based on what items are selected and there position in the dual list box. By
using the event firing I can bubble an even from the dual list box and then
use that event to fire the event that generates the dynamic portion of this
control. I’m quite sure this is not the correct nor is it the best way to
accomplish this but, it’s working so far. Here is an example of how I’m doing
this in the main portion of my program.

Sub ItemAddedToAssigned(ByVal sender As Object, ByVal e As EventArgs)
Handles dlbColumns.Assigned_change
dlbPriField.ClearDLB()

If Not dlbColumns.Assigned.Count.Equals(0) Then

Dim objItemCollection As New
System.Web.UI.WebControls.ListItemCollection
StringToListItemCollection(objItemCollection,
Settings("PrimaryField"))
Populate_dlb(dlbPriField, dlbColumns.Assigned, objItemCollection)

ddView.Fields = dlbColumns.Assigned
ddView.Raise_Build_Grid(sender, e)

End If
End Sub

To clarify this takes an event that occurred in dlbColumns and then makes
the changes in dlbPrimary and in ddview. dlbColumns and dlbPrimary are both
dual list controls, and ddview is this control. So, once again, I’m trying to
figure out if there is a better way to do what I’m doing right now, or if
anyone knows how I can get the data back from the fields after a user is done
entering data into them.

Thanks in advanced, Nathan Rover
 
M

Mike MacMillan

NateDawg,
with composite user controls such as you have, you need to keep in
mind when the framework is trying to restore data from viewstate. the
events you're concerned with fire in this order: OnInit, LoadPostData,
LoadViewState, OnLoad. basically, you need to make sure any dynamic
controls are created during the OnInit event, otherwise, when
LoadViewState fires, there wont be a control to restore the ViewState
value to. short answer: make the dynamic controls properties of the
class (or simply private/protected members), and instantiate them
during the OnInit event. you can still build your table as you do
during the OnLoad(Page_Load) event, but this way it will ensure your
controls will have their ViewState values restored during the
LoadViewState event.

let me know if you have any issues,
Mike MacMillan
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,755
Messages
2,569,539
Members
45,024
Latest member
ARDU_PROgrammER

Latest Threads

Top