ControlParameter can't find control which is in a UserControl

Go To StackoverFlow.com

2

I am fairly new to ASP.NET, but have been rolling right along, able to get past all hurdles thus far, with a little research. But I've got a little issue that I can't seem to get around, involving a custom control I've created.

The control is a little widget that pops-up via JQuery and contains controls for allowing the user to filter on a result set. I had all the elements of this pop-up embedded within two specific pages, and those pages were each working fine. I decided to create a custom control, and have done so correctly, so far as I can tell, using an ascx file with Control' directive and aRegister' directive on the target page, so:

<%@ Control Language="C#" AutoEventWireup="true" CodeBehind="PopUp_TopicFilterControl.ascx.cs" Inherits="POD.PopUp_TopicFilterControl" %>

And

<%@ Register TagPrefix="popup" TagName="TopicFilterControl" Src="~/Controls/PopUp_TopicFilterControl.ascx" %>

The `main' page contains an object datasource which needs to reference controls within my custom control for its select parameters. Here's the datasource:

<asp:ObjectDataSource ID="TopicDataSource" runat="server" SelectMethod="GetRecentTopics" TypeName="POD.App_Objects.Topic">
    <SelectParameters>
        <asp:Parameter DefaultValue="12" Name="select_limit" Type="Int32" />
        <asp:ControlParameter DefaultValue="" ControlID="TopicCategoryFilterList" Name="category" Type="String" />
        <asp:ControlParameter DefaultValue="" ControlID="TopicCreatorFilterList" Name="creator" Type="Int32" />
        <asp:ControlParameter DefaultValue="" ControlID="TopicDateAfterFilterText" Name="date_after" Type="String" />
        <asp:ControlParameter DefaultValue="" ControlID="TopicDateBeforeFilterText" Name="date_before" Type="String" />
    </SelectParameters>
</asp:ObjectDataSource>

And here is the body of the custom control:

<asp:Panel id="TopicFilter_Panel" runat="server" CssClass="PopUp" ClientIDMode="Static" EnableTheming="False" EnableViewState="False" ViewStateMode="Disabled">
    <asp:Panel runat="server" CssClass="PopUp_Heading">
        <h1><a id="TopicFilter_Close" href="#">Close [X]</a></h1>
    </asp:Panel>
    <asp:Panel runat="server" CssClass="PopUp_Body">
        <asp:Table runat="server">
            <asp:TableRow runat="server">
                <asp:TableCell runat="server" HorizontalAlign="Right">
                    By Category:
                </asp:TableCell>
                <asp:TableCell runat="server">
                    <asp:DropDownList
                        ID="TopicCategoryFilterList"
                        runat="server"
                        DataSourceID="TopicCategoryDataSource"
                        DataTextField="value"
                        DataValueField="value"
                        AppendDataBoundItems="True"
                        AutoPostBack="False">
                        <asp:ListItem Selected="True" Value="">&mdash; All &mdash;</asp:ListItem>
                    </asp:DropDownList>
                </asp:TableCell>
            </asp:TableRow>
            <asp:TableRow runat="server">
                <asp:TableCell runat="server" HorizontalAlign="Right">
                    By Author:
                </asp:TableCell>
                <asp:TableCell runat="server">
                    <asp:DropDownList
                        ID="TopicCreatorFilterList"
                        runat="server"
                        DataSourceID="UserDataSource"
                        DataTextField="person_name_full"
                        DataValueField="user_id"
                        AppendDataBoundItems="True"
                        AutoPostBack="False">
                        <asp:ListItem Selected="True" Value="">&mdash; All &mdash;</asp:ListItem>
                    </asp:DropDownList>
                </asp:TableCell>
            </asp:TableRow>
            <asp:TableRow runat="server">
                <asp:TableCell runat="server" HorizontalAlign="Right">
                    By Date (After):
                </asp:TableCell>
                <asp:TableCell runat="server">
                    <asp:TextBox ID="TopicDateAfterFilterText" runat="server" />
                    <ajaxToolkit:CalendarExtender ID="TopicDateAfterCalendarExtender" TargetControlID="TopicDateAfterFilterText" PopupPosition="BottomRight" runat="server" />
                </asp:TableCell>
            </asp:TableRow>
            <asp:TableRow runat="server">
                <asp:TableCell runat="server" HorizontalAlign="Right">
                    By Date (Before):
                </asp:TableCell>
                <asp:TableCell runat="server">
                    <asp:TextBox ID="TopicDateBeforeFilterText" runat="server" />
                    <ajaxToolkit:CalendarExtender ID="TopicDateBeforeCalendarExtender" TargetControlID="TopicDateBeforeFilterText" PopupPosition="BottomRight" runat="server" />
                </asp:TableCell>
            </asp:TableRow>
            <asp:TableRow>
                <asp:TableCell ColumnSpan="2" VerticalAlign="Bottom" HorizontalAlign="Center">
                    <asp:Button runat="server" Text="Apply" CssClass="PopUp_Apply" />
                </asp:TableCell>
            </asp:TableRow>
        </asp:Table>
    </asp:Panel>
</asp:Panel>

The error I'm getting is simply that the object datasource isn't seeing the controls inside my custom control (e.g., "Could not find control 'TopicCategoryFilterList' in ControlParameter 'category'"). Obviously a very simple matter, but I can't for the life of me seem to simply figure-out how to make this work. I'm quite certain this must've been addressed here, but I cannot find an example.

2012-04-04 19:27
by Michael Doleman
Well, okay, I've figured it out. Obviously (to me now), once the form controls are "inside" the custom control, they are not "visible" as such. They become properties of the custom control (duh). In the code behind page on the custom control, you must create a public property that returns the value of the control you are after, in your datasource control parameters. And then simply change your ControlParameter such that it asks for the name of the custom control in ControlID, and adds a PropertyName attribute that references the new property in the code behind. Got it - Michael Doleman 2012-04-04 21:10


2

Here is my own solution to this "issue," in case someone bumps into the same difficulty and spins their wheels as furiously as I did, to find the answer. First, here's a snippet of the code for returning a property of the custom control. I have this code sitting in the ascx.cs file:

public partial class PopUp_TopicFilterControl : System.Web.UI.UserControl
{

    public string TopicCategory
    {
        get { return TopicCategoryFilterList.SelectedValue.ToString(); }
    }

}

And here is the change to the ControlParameter inside the ObjectDataSource:

<asp:ControlParameter
    DefaultValue=""
    ControlID="TopicFilterSelection"
    PropertyName="TopicCategory"
    Name="category"
    Type="String" />

Note that all I've had to do is change the ControlID to the name of my custom control, and add the PropertyName attribute, which refers to the property that I defined in the ascx.cs file.

That's all there is to it. Obvious when you see it, but it had me stumped for quite a few hours.

2012-04-05 16:33
by Michael Doleman
As you said this makes perfect sense once you see it, but getting there does not. Awesome solution - Telavian 2014-06-13 00:52
Ads