While trying to create a custom User Control for a project I've been working on at work I discovered a few things that need to be done to add a Typed DataSource to a User Control and still have your data controls work
1: Unless you know the unique ClientID that will be given to your datasource at runtime you can remap the DataSourceID at runtime.
In the Page_Init of your user control set the datasource of your data control to the ClientID of your datasource control
Example:
protected
}
This essentially gets the ClientID of the datasource before the page actually starts to run and does the databinding/etc. Otherwise in a user control your ClientID gets a unique key prependend to the front of it consisting of it and your usercontrol ID.
2: Now if you run your page with the typed repeater control you will also need to change some code in the private ConnectToDataSourceView() method.
The control as-is will only work from the calling page itself and not in a lower hierarchy control like a user control. What we need to do is search for the control recursively. There is already a FormUtil.FindControls() method that is close, but it searches for Controls by ID instead of ClientID
We'll add a new method to the partial class FormUtil named FindControlByClientID() as follows:
return null; }
Now you can change the code for the Typed Repeater Control:
if (m_currentView == null) { MyNetTiers.Web.Data.MyDataSource datasource = null; // CHANGE HERE //Control ctl = this.Page.FindControl(DataSourceID); Control ctl = FormUtil.FindControlByClientID(this.Page, DataSourceID);
You of course should change this in the templates and it will always work recursively.
3: The final tip is dealing with ControlID parameters in your Typed Datasource.
So far I've only dealt with two controls <asp:ControlParameter /> and Typed SQL Filters. Lets start with an example datasource.
<DeepLoadProperties Method="IncludeChildren" Recursive="False"> <Types> <data:NewHomesProperty Name="MyDeepCollection" /> <data:NewHomesProperty Name="MyOtherDeepCollection" /> </Types></DeepLoadProperties>
</data:MyTableDataSource>
As you can see I have a MyTableDataSource that is calling the GetByID method of the Provider and is calling the values from the __Page control (the calling page). The problem is that this is a User Control and we want to store our properties in the code behind for the user control. This is going to be done in two steps. We'll start with the <asp:ControlParameter /> :
in the code behind for the Page_Init on your user control do as follows:
This gets the control parameter of Name="ID" from the datasource parameters and overrides the value of the ControlID with the scoped version of the custom User Control's ClientID. Now you can add a parameter in the code behind as follows:
That will get you the id from the request SomeRequestPageWithMyCustomUserControl.aspx?id=1
Now we need to deal with the filter. For this I turn to Generics to help me out. The biggest issue with the SqlParameters is they are nested such you cant find them by a ControlID. So first lets add another neat method to our FormUtil partial class.
public static
foreach (Parameter p in collection) {
if (p is SqlParameter) { SqlParameter s = p as SqlParameter; foreach (object filt in s.Filters) { if (filt is FilterType) { SqlFilter<FilterColumn> f = filt as SqlFilter<FilterColumn>; if (f.Column.Equals(column)) f.ControlID = controlId; } } } }}
This neat little creation of mine pulls apart the typed filters from the parameter list of the datasource and then changes the ControlID once it finds the correct column. In the Page_Init of your User Control do as follows:
Now you can add another Getter for this code behind:
public
Now you can put your new User Control on anything you want without errors =o)~
Enjoy!
Chris BertholdSoftrim CorporationEstero, FL