locked
Passing databound(Bind) data to a usercontrol inside templatefield(gridview) - uc acts different from normal controls RRS feed

  • Question

  • User425811032 posted

    Hello

    EDIT:
    I have attached here a little project that has the issue; there is a mdf database included so it's just compile and you'll see the problem when you suse the paging control where the usercontrol fails but the normal components work fine.
    https://ufile.io/pspmg it's packaged as a zip.
    Would love some help, I am unable to get this to work.

    I tried to do something smart but on the other hand have gotten myself into some more trouble.
    I wanted to populate a gridview control with 1 single row to avoid making a paging control myself.
    The problem is that no-matter what I do(will list below what I've tried) then I cant seem to pass data to the usercontrol from databound data(from gridview) as like any other normal control.
    to start off, i've created this to get passed data to my usercontrol: (Usercontrol c#)

     private string _eventSecret;
        public string eventSecret
        {
            get
            {
                return _eventSecret;
            }
            set
            {
                _eventSecret = value;
            }
        }

    And my usercontrol markup:

    MOST important
    <asp:SqlDataSource ID="SqlDataSource1" runat="server" ConnectionString="<%$ ConnectionStrings:ApplicationConn %>" SelectCommand="GetEventBySecret" SelectCommandType="StoredProcedure">
        <SelectParameters>
            <asp:Parameter Name="EventSecret" DbType="String" />
        </SelectParameters>
    </asp:SqlDataSource>
    REST IS NOT IMPORTANT

    I have now added the usercontrol above inside another usercontrol:

    <asp:SqlDataSource ID="SqlDataSource1" runat="server" ConnectionString="<%$ ConnectionStrings:Application %>" SelectCommand="GetEventsToPublic" SelectCommandType="StoredProcedure">
    </asp:SqlDataSource>
    <asp:GridView ID="GridView1" Width="100%" runat="server" AllowPaging="True" OnRowCreated="GridView1_RowCreated" onrowdatabound="GridView1_RowDataBound" AutoGenerateColumns="False" DataSourceID="SqlDataSource1" PageSize="1">
        <Columns>
            <asp:TemplateField HeaderText="EventSecret" ShowHeader="False">
                <ItemTemplate>
                    <asp:HiddenField ID="HiddenFieldEventSecret" runat="server" Value='<%# Bind("EventSecret") %>'></asp:HiddenField>
                    <uc1:EventSplash runat="server" eventSecret='<%# Bind("EventSecret") %>' ID="EventSplash" />
                </ItemTemplate>
            </asp:TemplateField>
        </Columns>
    </asp:GridView>

    When passing data from above code, then I for some reason then the hidden field vs the uc1 does not act the same.
    I am for example required to run DataBrind before the ic1 eventSecret is passed, futhermore, when paging I then get 'Object reference not set to an instance of an object.'.
    Why is it that the Hiddenfield/label/what ever standard control works fine, but passing the custom parameter eventSecret thought the same methods does not act the same?

    Do you guys have any idea how I can fix this?
    I thought of maybe databinding codebehind on both load and onindexchange? but how can I access the control and bind data from inside the gridview (without findcontrol)?
    Is there a better solution?

    (Ultra short overview; my user control evenSecret parameter does not function the same as a labels text, as for example I have to databind for my eventSecure to even be activated, but when paging the Gridview1.Databind in load does not fix it and throws a classic 'Object reference not set to an instance of an object.'.)
    - Please write if you find what I write too confusing - would like to know if anybody understand the issue.

    Thursday, May 3, 2018 5:04 PM

Answers

  • User-330142929 posted

    Hi zassadgh,

    As far as I know, the Databinding event occurred after Page_load, before Page_PreRender. After data bind, the Asp.Net web page will set the value to user control’s property. If you want to get the value from the property, you should put the codes in the Page_PreRender .

    I think it could be solved by the following solution. I made a slight change, wish it could be useful to you.

    Gif Demo.

    WebUserControlSplash

        public string eventSecret
        {
            get
            {
                object o = ViewState["eventSecret"];
                return ((o == null) ? String.Empty : (string)o);
            }
            set
            {
                ViewState["eventSecret"] = value;
            }
        }
        protected void Page_Load(object sender, EventArgs e)
        {
            
        }
        protected void Page_PreRender(object sender,EventArgs e)
        {
            if (!String.IsNullOrEmpty(eventSecret))
            {
                Button1.Text = eventSecret;
            }
            else
            {
                Button1.Text = "IsNullOrEmpty, Error Here!";
            }
        }

    For more details.

    Asp.Net Page Life Cycle

    If you still have any question, please feel free to let me know.

    Best Regards

    Abraham.

    • Marked as answer by Anonymous Thursday, October 7, 2021 12:00 AM
    Thursday, May 10, 2018 7:39 AM

All replies

  • User-1716253493 posted

    First, use two way binding bind() for single control property only, you can use eval for multiple controls with same parameter

    Hiddenfield value is string, you can bind it to any string, but i don't know what type of eventsecret property.

    Friday, May 4, 2018 7:01 AM
  • User425811032 posted

    eventSecret is a string type - with Eval I experience the same problem - that I have to databind for example, while all other controls auto bind when settign their for example text/value property - how would I use the two way binding bind()? could you elaborate on that? I cannot access the usercontrol directly as it is inside a gridview, and should I put it like: UserControlNameBlablah.DataBindings.Add("Text", SqlDataSource1, "secretEvent");, as then I get: The event 'Control.DataBinding' can only appear on the left hand side of += or -= , when I try and set it inside the onrowdatabound="GridView1_RowDataBound" with ((Controls_EventSplash)e.Row.FindControl("EventSplash")).DataBinding.Add("Text", SqlDataSource1, "secretEvent"); in code behind.

    See my below post with attached example of the issue, thank you.

    Friday, May 4, 2018 8:55 AM
  • User283571144 posted

    Hi zassadgh,

    According to your usercontrol codes, I couldn't understand your requirement clearly.

    Do you mean you want to set the SelectParameters  with gridview Bind value the in user control code behind?

    According to your codes, I couldn't reproduce your issue on my side.

    I suggest you could post more details codes about your user control and gridview(code behind and html codes).

    If you could post more details information, it will be more easily for us to find the solution.

    Best Regards,

    Brando

    Friday, May 4, 2018 9:00 AM
  • User425811032 posted

    https://ufile.io/pspmg project showcasing the issue.
    Even when I try to use the same code as the label control to pass the parameter it does not work like a component does;

    [
            Bindable(true),
            DefaultValue(""),
            PersistenceMode(PersistenceMode.InnerDefaultProperty)
            ]
        public virtual string eventSecret
        {
            get
            {
                object o = ViewState["eventSecret"];
                return ((o == null) ? String.Empty : (string)o);
            }
            set
            {
                ViewState["eventSecret"] = value;
            }
        }

    Been stuck for a while, am I missing something, is what I am, trying impossible (see attached test project above)

    Sunday, May 6, 2018 4:54 PM
  • User425811032 posted

    I have found that I need to add a DataBinderHandler, I am still unable to get this to work (add the DataBinderHandler to the splash usercontrol), so that databind will be set automatically at design time. do you guys have any idea how I should add to only accept text a simple text string, which I then use at load in my splash control.

    Tuesday, May 8, 2018 1:22 PM
  • User-330142929 posted

    Hi zassadgh,

    As far as I know, the Databinding event occurred after Page_load, before Page_PreRender. After data bind, the Asp.Net web page will set the value to user control’s property. If you want to get the value from the property, you should put the codes in the Page_PreRender .

    I think it could be solved by the following solution. I made a slight change, wish it could be useful to you.

    Gif Demo.

    WebUserControlSplash

        public string eventSecret
        {
            get
            {
                object o = ViewState["eventSecret"];
                return ((o == null) ? String.Empty : (string)o);
            }
            set
            {
                ViewState["eventSecret"] = value;
            }
        }
        protected void Page_Load(object sender, EventArgs e)
        {
            
        }
        protected void Page_PreRender(object sender,EventArgs e)
        {
            if (!String.IsNullOrEmpty(eventSecret))
            {
                Button1.Text = eventSecret;
            }
            else
            {
                Button1.Text = "IsNullOrEmpty, Error Here!";
            }
        }

    For more details.

    Asp.Net Page Life Cycle

    If you still have any question, please feel free to let me know.

    Best Regards

    Abraham.

    • Marked as answer by Anonymous Thursday, October 7, 2021 12:00 AM
    Thursday, May 10, 2018 7:39 AM