Understanding ObjectDataSource and Select Parameters
Asked Answered
T

3

6

I have in a GridView control a TemplateField like:

<asp:TemplateField ItemStyle-Width="150px">
   <ItemTemplate>
      <asp:DropDownList ID="ddlFields" runat="server" DataSourceID="odsOperator" DataTextField="Text" DataValueField="Value" />
      <asp:HiddenField ID="hfFieldType" runat="server" Value='<%# Eval("FieldType")%>' />
   </ItemTemplate>
</asp:TemplateField>

I have a dropdown that I want to populate from a ObjectDataSource, but for each line I want to pass a Select Parameter so it populates with the right values

<asp:ObjectDataSource ID="odsOperator" runat="server" TypeName="OperatorFieldsDAO"
   SelectMethod="FindByType">      
   <SelectParameters>
      <asp:ControlParameter ControlID="hfFieldType" Type="String" Name="Type" PropertyName="Value" />
   </SelectParameters>
</asp:ObjectDataSource>

my OperatorFieldsDAO class is:

public class OperatorFieldsDAO
{
    private List<OperatorField> OperatorFields
    {
        get
        {
            List<OperatorField> operatorFields = HttpContext.Current.Session["OperatorFields"] as List<OperatorField>;
            if (operatorFields == null)
            {
                operatorFields = new List<OperatorField>();
                operatorFields.Add(new OperatorField("string", "contains", "C"));
                operatorFields.Add(new OperatorField("string", "begins with", "BW"));
                operatorFields.Add(new OperatorField("string", "is equal to", "E"));
                operatorFields.Add(new OperatorField("string", "is not equal to", "NE"));
                operatorFields.Add(new OperatorField("string", "is less than", "L"));
                operatorFields.Add(new OperatorField("string", "is greater than", "G"));
                operatorFields.Add(new OperatorField("string", "is less than or equal to", "LE"));
                operatorFields.Add(new OperatorField("string", "is greater than or equal to", "GE"));
                operatorFields.Add(new OperatorField("string", "is from", "F"));
                operatorFields.Add(new OperatorField("string", "is between", "B"));
                operatorFields.Add(new OperatorField("string", "is nothing", "N"));
                operatorFields.Add(new OperatorField("string", "is something", "S"));

                operatorFields.Add(new OperatorField("number", "is the same as", "S"));
                operatorFields.Add(new OperatorField("number", "is not the same as", "S"));
                operatorFields.Add(new OperatorField("number", "is one of", "S"));
                operatorFields.Add(new OperatorField("number", "is not one of", "S"));
                operatorFields.Add(new OperatorField("number", "is nothing", "N"));
                operatorFields.Add(new OperatorField("number", "is something", "S"));
            }
            return operatorFields;
        }
    }
    public OperatorFieldsDAO() { }

    [DataObjectMethod(DataObjectMethodType.Select)]
    public IEnumerable<OperatorField> FindAll()
    {
        return this.OperatorFields;
    }

    [DataObjectMethod(DataObjectMethodType.Select)]
    public IEnumerable<OperatorField> FindByType(String type)
    {    
        List<OperatorField> r = new List<OperatorField>();

        foreach (OperatorField f in this.OperatorFields)
            if (f.Type == type)
                r.Add(f);

        return r;
    }
}

all of this to tell you that I get an error:

Could not find control 'hfFieldType' in ControlParameter 'Type'.

What am I doing wrong?

Do I need to programatically pass that selected parameter using the OnRowDataBound method?

Trinhtrini answered 6/8, 2009 at 10:23 Comment(0)
T
5

to get this working I add to create two methods (one for the GridView and other for the ObjectDataSource), as well change the Select Parameter from a ControlParameter to a normal Parameter.

The idea is to set the Parameter every time the row it's created...

protected void gvSearch_RowDataBound(object sender, GridViewRowEventArgs e)
{
    if (e.Row.RowType == DataControlRowType.DataRow)
    {
        DropDownList d = (DropDownList)e.Row.FindControl("ddlFields");
        string type = ((HiddenField)e.Row.FindControl("hfFieldType")).Value;

        _type = type;
        d.DataBind();
    }
}
protected void odsOperator_Selecting(object sender, ObjectDataSourceSelectingEventArgs e)
{
    e.InputParameters["Type"] = _type;
}

private string _type = "";

and the ObjectDataSource will be

<asp:ObjectDataSource ID="odsOperator" runat="server" TypeName="OperatorFieldsDAO"
   SelectMethod="FindByType" onselecting="odsOperator_Selecting">
   <SelectParameters>
      <asp:Parameter Type="String" Name="Type" />
   </SelectParameters>
</asp:ObjectDataSource>

I hope it helps anyone ...

Trinhtrini answered 7/8, 2009 at 6:36 Comment(0)
P
1

Since you have:

<asp:HiddenField ID="hfFieldType" runat="server" .../>

Within a TemplateField of your view, there may be none, one or many instances of that field on the page. Therefore hfFieldType would not be a unique ID, in fact the actual ID will be determined at runtime.

Thus your control parameter cannot find it since it is looking for its value in a property of a control called hfFieldType somewhere on the page.

I haven't worked with ObjectDataSource in a few years, but I suspect you might want to hook into the Selecting event.

Postliminy answered 6/8, 2009 at 10:36 Comment(0)
L
0

ObjectDataSource cannot find the control being used for input unless it's close by in the markup. The datasource has to be INSIDE the tag that contains the control used for input. It seems to be a scoping problem.

Labret answered 11/5, 2012 at 20:7 Comment(1)
Welcome to stackoverflow! It's always better to provide a sample code for your solution if possible to improve the post accuracy :)Meadowsweet

© 2022 - 2024 — McMap. All rights reserved.