Home All Groups Group Topic Archive Search About

DataControlFieldCollection instantiated twice

Author
27 Aug 2006 11:53 AM
Sam Terburg - Emanon
I'm trying to create my own GridView with some addons.
I'm realising that by creating a placeholder with a GridView and
SQLDataSource in it.
The problem is dat the fields defined in the DataFieldControlCollection
gets instantiated twice with which the second instantiation doesn't have
any attribute/property set.

Here is my code:
     <phaFramework:EditGrid
         id           = "E01"
         query        = "SELECT  bla FROM bla"
         runat        = "Server" >
         <Fields>
             <phaForm:frwNumericField
                 ID                          = "percentage"
                 HeaderText                  = "Percentage">
                 <validators>
                     <phaValidator:frwNumericValidator
                               minimalValue  = 0
                               maximumValue  = 10 />
                 </validators>
             </phaForm:frwNumericField>
         </Fields>
     </phaFramework:EditGrid>

Public Class EditGrid
     Inherits PlaceHolder

     Friend WithEvents baseGridView As New GridView
     Friend WithEvents baseDataSource As New SqlDataSource

     Public Sub New()
         Me.Controls.Add(Me.baseGridView)
         Me.Controls.Add(Me.baseDataSource)
     End Sub

     Public ReadOnly Property Fields() As FormFieldCollection
         Get
             If ViewState("Fields") Is Nothing Then
                 ViewState("Fields") = New FormFieldCollection(Me)
             End If
             Return ViewState("Fields")
         End Get
     End Property
End Class

Public Class FormFieldCollection
     Inherits List(Of iFormField)
End Class

     Public Class frwTextField
         Inherits TemplateField
         Implements iFormField, IBindableTemplate
         Protected arrValidators As New ValidatorCollection
         Public ReadOnly Property validators() As ValidatorCollection
             Get
                 Return Me.arrValidators
             End Get
         End Property
     End Class

Public Class ValidatorCollection
     Inherits List(Of BaseValidator)
End Class


Basicly that's it.
I have ofcourse simplified the code. It is mush more than this.
I've put logging (Trace) everythere and there i can see that the
frwNumericValidator is created and added to the List of validators.
When the Template of the field is instantiated (InstantiateIn called)
the validators collection is empty (count=0).
I can also see that the ValidatorCollection is created twice (the New
contstructor called twice).
what i think is that:
1) the FieldCollection is created by me with the New constructor
2) the FieldCollection is also created by restoring the ViewState.
And that in between the properties are set so that the second
instantiation doesn't have these properties set (these properties are
min/maxValues as can be seen as attributes of the aspx tag).

I've tried several options.
I've tried creating the FieldCollection as a StateManagedCollection
(like the GridView.columns). No success.

Can someone explain me how the .Net framework works?
What is it doing?


Sam.

Author
28 Aug 2006 9:13 AM
Steven Cheng[MSFT]
Hello Sam,

From your description, you're creating a custom webserver control which
inherits a placeholder and will composite some other inner controls like
custom GridView and validator controls. However, you found the custom
GridView's custom controlfield will behave unexpectedly on the
"instantiate" method, correct?

Based on the code fragement you provided, I found your custom control
"EditGrid"'s aspx template (inner tag and html) is like a Gridview control,
however, it inherts from placeholder. Would you tell him why you will
implement the control as this and not directly create a custom GridView
class that inhertis from GridView class?

As for GridView and its column(datacontrolfield), the "instantiate" is
automatically called by the GridView at databinding time instead of own
code, have you ever manually call it in your custom control?  

In addition, you can simply create a custom gridview class directly
inherits from Gridview and use some custom DatacontrolFields in it to see
whether the same problems remain.

Please feel free to let me know if there is anything I missed or any other
finding on this.

Sincerely,

Steven Cheng

Microsoft MSDN Online Support Lead


This posting is provided "AS IS" with no warranties, and confers no rights.
Author
28 Aug 2006 12:12 PM
Sam Terburg - Emanon
Steven Cheng[MSFT] wrote:
Show quote
> Hello Sam,
>
> From your description, you're creating a custom webserver control which
> inherits a placeholder and will composite some other inner controls like
> custom GridView and validator controls. However, you found the custom
> GridView's custom controlfield will behave unexpectedly on the
> "instantiate" method, correct?
>
> Based on the code fragement you provided, I found your custom control
> "EditGrid"'s aspx template (inner tag and html) is like a Gridview control,
> however, it inherts from placeholder. Would you tell him why you will
> implement the control as this and not directly create a custom GridView
> class that inhertis from GridView class?
>
> As for GridView and its column(datacontrolfield), the "instantiate" is
> automatically called by the GridView at databinding time instead of own
> code, have you ever manually call it in your custom control?  
>
> In addition, you can simply create a custom gridview class directly
> inherits from Gridview and use some custom DatacontrolFields in it to see
> whether the same problems remain.
>
> Please feel free to let me know if there is anything I missed or any other
> finding on this.
>
> Sincerely,
>
> Steven Cheng
>
> Microsoft MSDN Online Support Lead
>

> This posting is provided "AS IS" with no warranties, and confers no rights.
>
>

Hello Steven,

First of all thank you for your answer.

The reason inherited from a placeholder and not directory from GridView
is that my contractor doesn't want all those extra properties and only
want to see what is necessary for him. It confuses him.

By using the DataSourceID instead of the DataSource property of the
GridView a lot of binding is automated.
So i don't do any binding myself.

What i am doing is defining the FieldCollection with "Dim fields as new
FieldCollection"
So it is always created manually.
Perhaps somewhere it is again created by restoring a viewstate.
While i don't think the FieldCollection would fit in a viewstate (not
serializable because i have a property called parent which would it
create a recursive loop)

I'm not too keen on making a radical change like directly inhereting
from GridView. It would mean a lot of work.

So if you have some insight as how de framework works with instantiating
thing (restoring viewstate for example) then perhaps i can solve it the
way it is.


Regards,


Sam
Author
29 Aug 2006 7:12 AM
Steven Cheng[MSFT]
Hello Sam,

As for the ViewState management and how it is implemented, you can have a
look at the following msdn article:

#Understanding ASP.NET View State
http://msdn.microsoft.com/library/en-us/dnaspp/html/viewstate.asp?frame=true

though this article is targeting ASP.NET 1.1(ASP.NET 2.0 add the
IStateManager interface to support normal object's ViewState persistence),
the basic theory still remains.

As for how control and template is initialized and instanced, here is a
general steps about how template databound control is working(populate
control structure ) at runtime, I use GridView for instance:

1. At first time(not postback), the gridview will need to perform
databinding to create control structure(GridView rows). The detailed
process is:

** Get databound datasource object from DataSourceControl(or
programmtically assigned).

** In the CreateChildControl method, the control will create a GridViewRow
(header , footer, pager, item ....) for each row.

** Use the proper Template of each DatacontrolField (defined through the
columns collection) to instaniate the GridViewRow's control collection.

** evaluate databinding expression not handler that is necessary to
executed.

** control collection is constructed.....


2. When postback, the GridView will also construct the control collection
in CreateChildControls method, however, this time, instead of using
datasource and databound, it will create a dummy datasource object(just an
object array of the same length of row numbers) and Create the Same number
of GridViewRows and add them into GridView's control collection.   This
time, since it will not use template and databinding to instantiate the
GridViewRow and control collection, but restore the control collection from
ViewState ......


In order to have a clearer view on this, I suggest you use the reflector
tool to inspect the code logic of GridView control's control creation and
instantiate methods. the following ones are of importance:

protected override int CreateChildControls(IEnumerable dataSource, bool
dataBinding)

private GridViewRow CreateRow(int rowIndex, int dataSourceIndex,
........................)

protected virtual void InitializeRow(GridViewRow row, DataControlField[]
fields)

You can get the reflector tool at the following site:

http://www.aisto.com/roeder/dotnet/

Hope this helps.

Sincerely,

Steven Cheng

Microsoft MSDN Online Support Lead



This posting is provided "AS IS" with no warranties, and confers no rights.
Author
31 Aug 2006 9:25 AM
Steven Cheng[MSFT]
Hi Sam,

Any progress on this issue, does the information in my last reply helps a
little?

If there is anything else we can help, please feel free to let me know.

Sincerely,

Steven Cheng

Microsoft MSDN Online Support Lead


This posting is provided "AS IS" with no warranties, and confers no rights.
Author
28 Aug 2006 12:12 PM
Sam Terburg - Emanon
Steven Cheng[MSFT] wrote:
Show quote
> Hello Sam,
>
> From your description, you're creating a custom webserver control which
> inherits a placeholder and will composite some other inner controls like
> custom GridView and validator controls. However, you found the custom
> GridView's custom controlfield will behave unexpectedly on the
> "instantiate" method, correct?
>
> Based on the code fragement you provided, I found your custom control
> "EditGrid"'s aspx template (inner tag and html) is like a Gridview control,
> however, it inherts from placeholder. Would you tell him why you will
> implement the control as this and not directly create a custom GridView
> class that inhertis from GridView class?
>
> As for GridView and its column(datacontrolfield), the "instantiate" is
> automatically called by the GridView at databinding time instead of own
> code, have you ever manually call it in your custom control?  
>
> In addition, you can simply create a custom gridview class directly
> inherits from Gridview and use some custom DatacontrolFields in it to see
> whether the same problems remain.
>
> Please feel free to let me know if there is anything I missed or any other
> finding on this.
>
> Sincerely,
>
> Steven Cheng
>
> Microsoft MSDN Online Support Lead
>

> This posting is provided "AS IS" with no warranties, and confers no rights.
>
>

Hello Steven,

First of all thank you for your answer.

The reason inherited from a placeholder and not directory from GridView
is that my contractor doesn't want all those extra properties and only
want to see what is necessary for him. It confuses him.

By using the DataSourceID instead of the DataSource property of the
GridView a lot of binding is automated.
So i don't do any binding myself.

What i am doing is defining the FieldCollection with "Dim fields as new
FieldCollection"
So it is always created manually.
Perhaps somewhere it is again created by restoring a viewstate.
While i don't think the FieldCollection would fit in a viewstate (not
serializable because i have a property called parent which would it
create a recursive loop)

I'm not too keen on making a radical change like directly inhereting
from GridView. It would mean a lot of work.

So if you have some insight as how de framework works with instantiating
thing (restoring viewstate for example) then perhaps i can solve it the
way it is.


Regards,


Sam

AddThis Social Bookmark Button