Home | Contact Us | FAQ | Search & Site Map | Link to Us
Sign In | Join | Other 45 Sites in Network
HomeAnnouncementsFree MagazinesWhite PapersSubmit Content
Discussion GroupsASP.NETWindows FormsLanguages.NET FrameworkVisual Studio.NET
Articles.NET FrameworkASP.NETToolsWindows Forms
.NET DirectoryOpen Source ProjectsUser GroupsWeb Resources
Related Topics
Visual Basic 6SQL ServerMS AccessOther DB ProductsMS Server ProductsMore Topics ...

.NET Forum / ASP.NET / Building Controls / June 2006

Tip: Looking for answers? Try searching our database.

Custom Datagrid Implementation

Thread view: 
Enable EMail Alerts  Start New Thread
Thread rating: 
Brent Ritchie - 28 Jun 2006 16:47 GMT
Hello,

   I have been given the assignment of creating a custom datagrid for
our company. The specs are pretty simple: 1) Use a webservice to
populate and do other processing tasks.

   So far I made a test web service and derived it from a common
interface. The Custom datagrid uses this interface to call methods of
the webservice. This is ok. The problem I have is that when the
datagrid is created, I cannot create any of the dynamic controls until
I bind to the data and I cannot bind to the data until after the
control has been created.

   Given this, how would I go about setting the viewstate / postdata
manually on all of these controls.
Brent Ritchie - 28 Jun 2006 20:35 GMT
I've decided to post the source of what I have now. I don't think that
my previous description was clear after reading it again.

Imports System.Text
Imports System.ComponentModel
Imports System.Web.UI
Imports System.Web.UI.WebControls
Imports IWebServices

<ToolboxData("<{0}:FLSDataGrid runat=server></{0}:FLSDataGrid>")> _
Public Class FLSDataGrid
   Inherits System.Web.UI.WebControls.DataGrid

#Region "Public Methods"

#Region "Constructors"

   Public Sub New()

       MyBase.New()
       Me.EnableViewState = True

       m_addrow = New DataGridItem(-1, -1, ListItemType.SelectedItem)

       Me.ViewState.Add("m_SortCriteria", "")
       Me.ViewState.Add("m_SortDirection", "ASC")
       Me.ViewState.Add("m_SearchEnabled", False)

   End Sub

#End Region

#End Region

#Region "Public Properties"

   Public Property WebDataSource() As IDataWebService
       Get
           Return m_WebDataSource
       End Get
       Set(ByVal Value As IDataWebService)
           m_WebDataSource = Value
           MyBase.VirtualItemCount =
m_WebDataSource.RetrieveRowCount()
           Me.PageEvent(Me, New DataGridPageChangedEventArgs(Me,
Me.CurrentPageIndex))
       End Set
   End Property

   Private Property TextFieldsNeeded()
       Get
           If Not Me.ViewState.Item("m_TextFields") = Nothing Then
               Return Me.ViewState.Item("m_TextFields")
           Else
               Return 0
           End If
       End Get
       Set(ByVal Value)
           Me.ViewState.Item("m_TextFields") = Value
       End Set
   End Property

   Public Property SearchEnabled() As Boolean
       Get
           Return Me.ViewState.Item("m_SearchEnabled")
       End Get
       Set(ByVal Value As Boolean)
           Me.ViewState.Item("m_SearchEnabled") = Value
       End Set
   End Property

   Public Property SortCriteria() As String
       Get
           Return Me.ViewState.Item("m_SortCriteria")
       End Get
       Set(ByVal Value As String)
           Me.ViewState.Item("m_SortCriteria") = Value
       End Set
   End Property

   Public Property SortDirection() As String
       Get
           Return Me.ViewState.Item("m_SortDirection")
       End Get
       Set(ByVal Value As String)
           Me.ViewState.Item("m_SortDirection") = Value
       End Set
   End Property

#End Region

#Region "Protected Methods"

   Protected Overrides Sub Render(ByVal output As
System.Web.UI.HtmlTextWriter)

       MyBase.Render(output)

   End Sub

   Protected Friend Overloads Sub OnPreRender(ByVal e As EventArgs)
       For Each c As Label In MyBase.Controls
           c.EnableViewState = False
       Next
       Me.CreateAndRegisterScripts()
       Me.CreateFooter()
   End Sub

   Protected Sub Sort(ByVal sender As Object, ByVal e As
DataGridSortCommandEventArgs) Handles MyBase.SortCommand

       If SortCriteria = e.SortExpression Then
           If SortDirection = "ASC" Then
               SortDirection = "DESC"
           Else
               SortDirection = "ASC"
           End If
       Else
           SortCriteria = e.SortExpression
           SortDirection = "DESC"
       End If

       Me.PageEvent(Me, New DataGridPageChangedEventArgs(Me,
Me.CurrentPageIndex))

   End Sub

   Protected Overloads Overrides Sub LoadViewState(ByVal savedState As
Object)

       MyBase.LoadViewState(savedState)

       For Each str As String In Me.ViewState.Keys
           If str.StartsWith("txtAddRow") Then
               Page.Response.Write(Me.ViewState.Item(str))
           End If
       Next
       Me.CreateFooter()

   End Sub

   Protected Sub PageEvent(ByVal sender As Object, ByVal e As
DataGridPageChangedEventArgs) Handles MyBase.PageIndexChanged

       MyBase.CurrentPageIndex = e.NewPageIndex
       If SearchEnabled = True Then

           Dim param As DataSet = New DataSet("Search Parameters")
           param.Tables.Add("Parameters")

param.Tables("Parameters").Rows.Add(param.Tables("Parameters").NewRow())

           Dim editcolumn As Boolean = True
           Dim ii As Integer = 0

           For Each tc As TableCell In m_addrow.Cells

               If editcolumn Then

                   editcolumn = False

               Else

                   param.Tables("Parameters").Columns.Add("@" +
DirectCast(MyBase.DataSource,
DataSet).Tables(0).Columns(ii).ToString())
                   param.Tables("Parameters").Rows(0).Item(ii) =
Me.ViewState.Item(DirectCast(tc.Controls(0), TextBox).ID).ToString()
                   ii += 1

               End If

           Next

           MyBase.DataSource = WebDataSource.RetrieveRecord(param)

       Else

           MyBase.DataSource =
WebDataSource.RetrieveRowsSubset(e.NewPageIndex, MyBase.PageSize,
Me.SortCriteria, Me.SortDirection)

       End If

       MyBase.DataBind()
       Me.CreateFooter()

   End Sub

   Protected Sub EditEvent(ByVal sender As Object, ByVal e As
DataGridCommandEventArgs) Handles MyBase.EditCommand

       Me.EditItemIndex = e.Item.ItemIndex
       Me.PageEvent(Me, New DataGridPageChangedEventArgs(Me,
Me.CurrentPageIndex))

   End Sub

   Protected Sub CancelEvent(ByVal sender As Object, ByVal e As
DataGridCommandEventArgs) Handles MyBase.CancelCommand

       Me.EditItemIndex = -1
       Me.PageEvent(Me, New DataGridPageChangedEventArgs(Me,
Me.CurrentPageIndex))

   End Sub

   Protected Sub UpdateEvent(ByVal sender As Object, ByVal e As
DataGridCommandEventArgs) Handles MyBase.UpdateCommand

       Me.PageEvent(Me, New DataGridPageChangedEventArgs(Me,
Me.CurrentPageIndex))

       Dim param As DataSet = New DataSet("Update Parameters")
       param.Tables.Add("Parameters")

param.Tables("Parameters").Rows.Add(param.Tables("Parameters").NewRow())

       Dim editcolumn As Boolean = True
       Dim deletecolumn As Boolean = True
       Dim i As Integer = 0

       For Each tc As TableCell In e.Item.Cells
           If editcolumn Then
               editcolumn = False
           ElseIf deletecolumn Then
               deletecolumn = False
           Else

               Dim tb As TextBox = tc.Controls(0)
               param.Tables("Parameters").Columns.Add("@" +
DirectCast(MyBase.DataSource, DataSet).Tables(0).Columns(i).ToString())
               param.Tables("Parameters").Rows(0).Item(i) = tb.Text
               i += 1

           End If
       Next

       Me.WebDataSource.UpdateRecord(param)
       Me.EditItemIndex = -1
       Me.PageEvent(Me, New DataGridPageChangedEventArgs(Me,
Me.CurrentPageIndex))

   End Sub

   Protected Sub DeleteEvent(ByVal sender As Object, ByVal e As
DataGridCommandEventArgs) Handles MyBase.DeleteCommand

       Me.PageEvent(Me, New DataGridPageChangedEventArgs(Me,
Me.CurrentPageIndex))

       Dim param As DataSet = New DataSet("Update Parameters")
       param.Tables.Add("Parameters")

param.Tables("Parameters").Rows.Add(param.Tables("Parameters").NewRow())

       Dim editcolumn As Boolean = True
       Dim deletecolumn As Boolean = True
       Dim i As Integer = 0

       For Each tc As TableCell In e.Item.Cells
           If editcolumn Then
               editcolumn = False
           ElseIf deletecolumn Then
               deletecolumn = False
           Else

               param.Tables("Parameters").Columns.Add("@" +
DirectCast(MyBase.DataSource, DataSet).Tables(0).Columns(i).ToString())
               param.Tables("Parameters").Rows(0).Item(i) = tc.Text
               i += 1

           End If
       Next

       Me.WebDataSource.DeleteRecord(param)
       Me.EditItemIndex = -1
       Me.PageEvent(Me, New DataGridPageChangedEventArgs(Me,
Me.CurrentPageIndex))

   End Sub

   Protected Sub AddRecordEvent(ByVal sender As Object, ByVal e As
EventArgs)

       Me.PageEvent(Me, New DataGridPageChangedEventArgs(Me,
Me.CurrentPageIndex))

       Dim param As DataSet = New DataSet("Update Parameters")
       param.Tables.Add("Parameters")

param.Tables("Parameters").Rows.Add(param.Tables("Parameters").NewRow())

       Dim editcolumn As Boolean = True
       Dim i As Integer = 0

       For Each tc As TableCell In m_addrow.Cells
           If editcolumn Then
               editcolumn = False
           Else

               param.Tables("Parameters").Columns.Add("@" +
DirectCast(MyBase.DataSource, DataSet).Tables(0).Columns(i).ToString())
               param.Tables("Parameters").Rows(0).Item(i) =
Me.ViewState.Item(DirectCast(tc.Controls(0), TextBox).ID).ToString()
               i += 1

           End If
       Next

       Me.WebDataSource.InsertRecord(param)

       Me.PageEvent(Me, New DataGridPageChangedEventArgs(Me,
Me.CurrentPageIndex))

   End Sub

#End Region

#Region "Private Methods"

   Private Sub FLSDataGrid_Init(ByVal sender As Object, ByVal e As
System.EventArgs) Handles MyBase.Init

       Me.SetDefaultAttributes()
       Me.CreateDynamicControls()
       Me.CreateAndRegisterScripts()

   End Sub

   Private Sub SetDefaultAttributes()

       MyBase.AllowPaging = True
       MyBase.AllowCustomPaging = True
       MyBase.AllowSorting = True

   End Sub

   Private Sub CreateDynamicControls()

       Dim ecc As EditCommandColumn = New EditCommandColumn
       ecc.EditText = "Edit"
       ecc.CancelText = "Cancel"
       ecc.UpdateText = "Save"
       MyBase.Columns.Add(ecc)

       Dim bc As ButtonColumn = New ButtonColumn
       bc.ButtonType = ButtonColumnType.LinkButton
       bc.Text = "Delete"
       bc.CommandName = "Delete"

       MyBase.Columns.Add(bc)

       m_AddBtn = New LinkButton
       m_AddBtn.EnableViewState = True
       m_AddBtn.ID = "m_AddBtn"
       m_AddBtn.Text = "Add "
       m_AddBtn.Visible = True
       m_AddBtn.Attributes.Add("onClick", "ConfirmSave()")
       AddHandler m_AddBtn.Click, AddressOf Me.AddRecordEvent

       m_PlaceHolderAdd = New PlaceHolder
       m_PlaceHolderAdd.EnableViewState = False
       m_PlaceHolderAdd.Controls.Add(m_AddBtn)

       m_SearchBtn = New LinkButton
       m_SearchBtn.EnableViewState = False
       m_SearchBtn.ID = "m_SearchBtn"
       m_SearchBtn.Text = " Search"
       m_SearchBtn.Visible = True
       AddHandler m_SearchBtn.Click, AddressOf Me.SearchRecordEvent

       m_PlaceHolderSearch = New PlaceHolder
       m_PlaceHolderSearch.EnableViewState = True
       m_PlaceHolderSearch.Controls.Add(m_SearchBtn)

   End Sub

   Private Sub CreateAndRegisterScripts()

       Dim ConfirmSaveFunction As String = "<SCRIPT
language='JavaScript'>function ConfirmSave() { if (confirm('Proceed
with saving new record?')) return true; if (document.all &&
window.event) event.returnValue = false; return false; }</SCRIPT>"
       Dim ConfirmDeleteFunction As String = "<SCRIPT
language='JavaScript'>function ConfirmDelete() { if (confirm('Proceed
with deleting record?')) return true; if (document.all && window.event)
event.returnValue = false; return false; }</SCRIPT>"
       Page.RegisterClientScriptBlock("ConfirmSave",
ConfirmSaveFunction)
       Page.RegisterClientScriptBlock("ConfirmDelete",
ConfirmDeleteFunction)

       Dim DeleteConfirm As String = " <SCRIPT language='JavaScript'>
" + _
       " for(i=0;i<document.links.length;i++) " + _
       " { " + _
       " var x = document.links[i]; " + _
       " if(x.innerText==" + ControlChars.Quote + "Delete" +
ControlChars.Quote + ") " + _
       " x.onclick = ConfirmDelete; " + _
       " continue; " + _
       " } " + _
       " </SCRIPT> "

       Page.RegisterStartupScript("DeleteConfirm", DeleteConfirm)

   End Sub

   Private Sub CreateFooter()

       Dim row As DataGridItem = New DataGridItem(-1, -1,
ListItemType.SelectedItem)
       Dim arr As New ArrayList
       Dim firstControl As Boolean = True
       Dim i As Integer = 0

       For Each a As TableCell In MyBase.Items.Item(0).Cells
           If a.Controls.Count > 0 Then
               If firstControl Then

                   Dim b As TableCell = New TableCell
                   b.Controls.Add(m_PlaceHolderAdd)
                   b.Controls.Add(m_PlaceHolderSearch)
                   firstControl = False
                   arr.Add(b)

               End If

               arr(0).ColumnSpan += 1

           Else

               Dim b As TableCell = New TableCell
               Dim c As TextBox = New TextBox
               c.ID = "txtAddRow" + i.ToString()
               If Not Page.IsPostBack Then
                   Me.ViewState.Add(c.ID, "")
               End If
               c.Text = Me.ViewState.Item(c.ID)
               ' c.Text = Page.Request.Form.Item(c.ID)
               AddHandler c.TextChanged, AddressOf Me.TXT_Unload
               b.controls.Add(c)
               arr.Add(b)
               i += 1

           End If
       Next

       For Each a As TableCell In arr
           row.Cells.Add(a)
       Next

MyBase.Controls(0).Controls.AddAt(MyBase.Controls(0).Controls.Count -
2, row)
       m_addrow = row

       For Each dgi As DataGridItem In Me.Items
           For Each tc As System.Web.UI.WebControls.TableCell In
dgi.Cells
               If Not tc.HasControls() Then
                   tc.EnableViewState = False
               End If
           Next
       Next

   End Sub

   Private Sub TXT_Unload(ByVal sender As Object, ByVal e As
System.EventArgs)

       Me.ViewState.Item(sender.id) = DirectCast(sender, TextBox).Text

   End Sub

   Private Sub SearchRecordEvent(ByVal sender As Object, ByVal e As
System.EventArgs)

       Me.SearchEnabled = True
       Me.PageEvent(Me, New DataGridPageChangedEventArgs(Me,
Me.CurrentPageIndex))

   End Sub

#End Region

#Region "Private Members"

   Private m_WebDataSource As IDataWebService
   Private m_AddBtn As LinkButton
   Private m_SearchBtn As LinkButton
   Private m_PlaceHolderAdd As PlaceHolder
   Private m_PlaceHolderSearch As PlaceHolder
   Private m_addrow As DataGridItem

#End Region

End Class
Alessandro Zifiglio - 29 Jun 2006 10:37 GMT
hi Brent, try overriding CreateControlHierarchy method of your base datagrid
control. eg.

Protected Overrides Sub CreateControlHierarchy ( _
useDataSource As Boolean _
)

MyBase.CreateControlHierarchy(useDataSource) ' call the base method.
'  now that the control hierarchy that is used
'  to render the DataGrid is created, lets start creating our custom
controls.
' Since the controls have already been created via our
' call to MyBase.CreateControlHierarchy(), you'd be looping
' through each row of the rendered datagrid to add
' your custom controls. Is this what you were after ?
' Further you asked about viewstate so :
If (useDataSource) Then
' this means there is nothing in viewstate,
' since we are rendering the first time.
Else
' no need to get data from the underlying datasource since
' we are going to be rendering from viewstate, probably a postback scenario
End if
End Sub

Alessandro Zifiglio

> I've decided to post the source of what I have now. I don't think that
> my previous description was clear after reading it again.
[quoted text clipped - 494 lines]
>
> End Class
Brent Ritchie - 29 Jun 2006 16:09 GMT
> hi Brent, try overriding CreateControlHierarchy method of your base datagrid
> control. eg.
[quoted text clipped - 22 lines]
>
> Alessandro Zifiglio

After Some quick changes for testing. This is exactly what I needed.
Just to be clear though, CreateControlHierarchy() happens after the
binding but just before rendering? I've been looking through the
Lifecycle examples and haven't seen this before.

The reason I asked about viewstate is that the controls are being
created so late that they don't have a chance for there viewstate or
postback data to be restored automatically. I needed viewstate to be
available after the controls are created to manually repopulate them.

Thanks, this was what I needed.
Alessandro Zifiglio - 29 Jun 2006 16:53 GMT
Brent, CreateControlHierarchy() is a method exposed by the datagrid, which
is actually called from CreateChildControls() method with an argument of
false, when its the first time the control is rendering. For all other
times, CreateControlHierachy() is called with an argument of true from
within the OnDataBinding method, so populating the data from the underlying
datasource itself and not viewstate.

Glad that helped you.
Have a good day,
Alessandro Zifiglio

>> hi Brent, try overriding CreateControlHierarchy method of your base
>> datagrid
[quoted text clipped - 36 lines]
>
> Thanks, this was what I needed.
Alessandro Zifiglio - 29 Jun 2006 17:05 GMT
oops :X
I mean the exact opposite of what i stated earlier, so to avoid confusion
this is exactly what i was trying to state  :
CreateControlHierarchy is called from within the CreateChildControls method
with an argument of false when the control understands that it needs to
populate the datacontrol from viewstate and not from the underlying
datasource.

while otherwise, CreateControlHierarchy() is called with an argument of true
from onDataBinding() method and gets the data from the underlying
datasource, which is triggered when the DataBind() method on your
datacontrol is called.

Apologies for confusion.
Regards,
Alessandro Zifiglio

> Brent, CreateControlHierarchy() is a method exposed by the datagrid, which
> is actually called from CreateChildControls() method with an argument of
[quoted text clipped - 47 lines]
>>
>> Thanks, this was what I needed.

Free Magazines

Get these publications absolutely FREE for up to 12 months. There are no hidden fees and no obligation. Simply choose a title, complete the application form and submit it. Read more ...

Oracle MagazineNetwork ComputingComputer WorldBio-IT WorldeWeekInformation WeekInfosecurity
 
Sign In
Join
My Latest Posts
My Monitored Threads
My Blog
My Photo Gallery
My Profile
My Homepage

Start New Thread
Enable EMail Alerts
Rate this Thread



©2009 Advenet LLC   Privacy Policy - Terms of Use
This website includes both content owned or controlled by Advenet as well as content owned or controlled by third parties.