DataControlFieldCollection instantiated twice

  • Thread starter Sam Terburg - Emanon
  • Start date
S

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.
 
S

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.
 
S

Sam Terburg - Emanon

Steven said:
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
 
S

Sam Terburg - Emanon

Steven said:
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
 
S

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.
 
S

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.
 

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

Top