DataBinding to SubProperties

J

Jason

I have built a custom control that has, as one of its properties, a
collection of another custom control. So controlA has property of type
controlBCollection. At design time it looks like:

<asp:controlA runat="server">
<asp:controlB commandName="Save"
commandArg="<%#DataBinder.Eval(Container, "DataItem.pkID")%>" />
</asp:controlA>

In a DataGrid i have a TemplateColumn with the above as the ItemTemplate
After binding there is nothing for the commandName or commandArg properties.
string.empty is the value for these properties.

if i bind the same thing directly to controlA, say...ToolTip, the values
show up.

Somehow the values from the datasource are not getting down to the
subproperties.

Any help would be greatly appreciated. Let me know if you need clarification
or even the source code and i'll be happy to provide.
 
W

Walter Wang [MSFT]

Hi,

Thank you for your post.

If it's possible, you can just post some key class here. Or you can send
the repro project to me. My email address is my newsgroup account (removing
the 'online.' part). I'll be glad to work with you on this issue.

Regards,
Walter Wang
Microsoft Online Community Support

==================================================
When responding to posts, please "Reply to Group" via your newsreader so
that others may learn and benefit from your issue.
==================================================

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

Walter Wang [MSFT]

Hi,

I've got your sample code and thank you for your effort on this.

Currently I am still performing research on this issue and will get back to
you as soon as possible. I appreciate your patience.

Regards,
Walter Wang ([email protected], remove 'online.')
Microsoft Online Community Support

==================================================
When responding to posts, please "Reply to Group" via your newsreader so
that others may learn and benefit from your issue.
==================================================

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

Walter Wang [MSFT]

Hi,

Sorry for reply so late.

When using Data-Binding expressions (<%# ... %>) to declaratively set
properties, it internally will use the control's DataBinding event to set
the property. So the method DataBind() must be called internally to make
the Data-Binding expressions work. The DataBind() call will be recursive,
i.e., calling Page.DataBind() will cause all child controls' DataBind()
gets called.

When using "DataBinder.Eval(Container, ...)", the Container is a keyword
which will be interpreted to Control.BindingContainer by the page Parser,
you can verify this by inspecting the generated page class source code.
Control.BindingContainer will normally return Control.NamingContainer,
unless it implements INonBindingContainer (which is an internal interface):

public Control BindingContainer
{
get
{
Control control1 = this.NamingContainer;
while (control1 is INonBindingContainer)
{
control1 = control1.BindingContainer;
}
return control1;
}
}

In your sample code, the ImgToolBar has attribute ParseChild(true), so that
the ImgToolBarButtons enclosed in its tag are parsed as properties of the
ImgToolBar rather than as child controls. Based on my research, the
DataBind() method of ImgToolBarButton never gets called. Even the
DataBind() method of ImgToolBarButton gets called, since its
BindingContainer will be ImgToolBar (rather than DataGridItem when the
binding occurred on ImgToolBar), the evaluation of "DataItem.pkID" will not
succeed.

I think the correct and complicate solution to this problem would be
implementing the ImgToolBar as a data-bound control (inherit from
ListControl or CompositeDataBoundControl).

For now, since what you needed is the current row's record ID, one possible
workaround would be:
1) Bind the ID to the ImgToolBar, we can create a general purpose Tag
property for the ImgToolBar:

public object Tag
{
get { return ViewState["Tag"]; }
set { ViewState["Tag"] = value; }
}

And bind the "pkID" field to this property:

<asp:TemplateField>
<ItemTemplate>
<c:ImgToolBar ID="toolbar1"
Tag=<%# DataBinder.Eval(Container, "DataItem.ProductID") %>
runat="server">
<c:ImgToolBarButton ID="button1" runat="server"
OnButtonClick="OnCommandEvent" ButtonType="copy" />
</c:ImgToolBar>
</ItemTemplate>
</asp:TemplateField>

2) Then we can get this Tag from ImgToolBarButton's Click event:

protected void OnCommandEvent(object sender, CommandEventArgs e)
{
if (sender is ImgToolBarButton)
{
ImgToolBar tb = (sender as ImgToolBarButton).Parent as
ImgToolBar;
int id = (int) (tb.Tag);
string name = e.CommandName;
}
}

Hope this helps. Please feel free to post here if anything is unclear.


Regards,
Walter Wang ([email protected], remove 'online.')
Microsoft Online Community Support

==================================================
When responding to posts, please "Reply to Group" via your newsreader so
that others may learn and benefit from your issue.
==================================================

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

Members online

Forum statistics

Threads
473,755
Messages
2,569,535
Members
45,007
Latest member
obedient dusk

Latest Threads

Top