views:

326

answers:

1

I have an ASP.Net detailsview control. Its DataSourceId varies and I set it in Page_load accordingly... (based on LLBLgen sub types, but this is not too important)

I guess this is a page lifecycle leaky abstraction I am not "getting".

The problem is that I bind to fields that may or may no be there depending on the datasource...

To "disable" a bound field under certain conditions I've tried wrapping the bound field in a panel which I set to visible or invisible in code-behind, but I still get the following error:

Sys.WebForms.PageRequestManagerServerErrorException: DataBinding: Entity does not contain a property with the name 'FilePrefix'.

I change the detaislview.datasourceid in pageload...might be too late in lifecycle.

I don't want to bind to that field, as it doesn't exist for the new datasource, but it tries to do so none-the-less and I get the error.

Any ideas? ;)

[Edited]: Code as requested...

ASP, detailsview bound column:

<asp:TemplateField>
<ItemTemplate>
<asp:Panel ID="pnlNormalAdditionalFields" runat="server" Visible="false">
    <asp:textbox id="txtFilePrefix" runat="server" MaxLength="250" Width="180px" text='<%# Bind("FilePrefix") %>'></asp:textbox>
    <asp:requiredfieldvalidator id="valFilePrefix" runat="server" errormessage="File Prefix is required." controltovalidate="txtFilePrefix">*</asp:requiredfieldvalidator>
</asp:Panel>
</ItemTemplate>
            </asp:TemplateField>

Code-behind: (determine datasource, detaislview is visible on postback only as grid is displayed in initial page load.)

    protected void Page_Load(object sender, EventArgs e)
    {
        if (!Page.IsPostBack) //initial load
        {
        }
        else //postback
        {
            //set customdatasource for grid & detailsview 
            switch (radAccountType.SelectedValue)
            {
                case "Normal":
                    dvAccount.DataSourceID = "NormalCollectionDataSource";
                    AccountRadGrid.customDataSourceId = "NormalCollectionDataSource";
                    break;
                case "Reseller":
                    dvAccount.DataSourceID = "ResellerCollectionDataSource";
                    AccountRadGrid.customDataSourceId = "ResellerCollectionDataSource";
                    break;

...

Show/hide panel:

        protected void dvAccount_OnPreRender(object sender, EventArgs e)
        {
            Panel pnlGroupStoreAdditionalFields = ControlHelper.FindControlFromTop(this, "pnlGroupStoreAdditionalFields", null) as Panel;

                pnlGroupStoreAdditionalFields.Visible = false;

                switch (radAccountType.SelectedValue)
                {
...
                    case "GroupStore":
                        ddlAccountType.SelectedValue = Constants.Account.Type.GroupStore;
                        pnlGroupStoreAdditionalFields.Visible = true;
                        break;
                }
            }

    }
A: 

Hey,

You can't assign a <%# Bind("") %> statement if the field isn't there; you would have to programmbly assign the value from code-behind if the value may or may not be there... using findcontrol to find the control from the specific item.

Brian
How?protected void SomeField_OnDataBinding(object sender, EventArgs e){ ((TextBox)sender).Text = Eval("SomeField").ToString();}Only Eval() is available, not Bind().Eval is read-only, I need to be able to auto push the value in the textbox back into the database... as is done with <%# Bind("") %>
Konrad
OK, if you need the auto push back, then you need to ensure that field exists in both data sources, even though it's always null in the other data source... that is the only way that i know of using DataSourceID.
Brian
I'll accept your answer. I'll have to manually bind in the detailsview OnItemInserting/Updating event... there I have more control and can disable fields not required that way.
Konrad