0

I would like to know the best way to directly assign properties to a dynamically created UserControl bound to an asp:Repeater. Consider the following code.

In the codebehind for the UserControl "MyControlType":

public bool IsRetained = false;

In the Page code:

<%@Register TagPrefix="pre" TagName="MyControlType" Src="~/MyPath/MyControl.ascx" %>

<asp:Repeater ID="repeater" DataSource='<%#dataSource%>' runat="server">
    <ItemTemplate>
        <pre:MyControlType runat="server" />
    </ItemTemplate>
</asp:Repeater>
<asp:Button OnClick="someButton_Click" Text="Add First Item" runat="server" />

In the Page codebehind:

protected List<MyControlType> dataSource = new List<MyControlType>();

protected void someButton_Click(object sender, EventArgs e)
{
    MyControlType myItem = (MyItem)Page.LoadControl("~/MyMath/MyControlType.ascx");
    dataSource.Add(myItem);
    myItem.IsRetained = true;
    repeater.DataBind();

    // test code
    MyControlType realItem = repeater.Items[0].Controls[1] as MyControlType;
    bool test0 = realItem.IsRetained; // false
    bool test1 = myItem == realItem; // false
}

A new MyControlType is successfully bound to the Repeater and displayed on the page, but it does not have the IsRetained value that I set. It is also not the same MyControlType instance as the one that I assigned to dataSource.

I can accomplish what I want to by obtaining a reference to the created MyControlType similarly to how I did with realItem in the example above, but I would prefer assign the property directly through myItem. Can anyone provide a method of doing so? It would also be nice to understand why test0 and/or test1 are false. Thanks!

chris4600
  • 183
  • 9

1 Answers1

0

EDIT:

There are few issues with your approaches:

  1. You are creating List<MyControlType> and trying to use it as datasource.

  2. You are initializing and adding myItem to the List and hoping that after Databinding you can find the UserControl in Repeater.

  3. You are adding the UserControl to the Repeater in markup and after DataBinding you are finding the repeater in repeater's item and hoping that it will have the value you have assigned to myItem.

Solution: Use a better DataSource to test, e.g. List<string>. Here's how the repeater might look(in repescet to test data):

<asp:Repeater ID="repeater" runat="server">
    <ItemTemplate>
        <pre:MyControlType IsRetained='<%#Container.DataItem == "item 1" ? true : false %>' runat="server" />
    </ItemTemplate>
</asp:Repeater>

And in my code I am testing like this:

protected void someButton_Click(object sender, EventArgs e)
{
    var lst = new List<string>() { "item 1", "item 2", "item 3" };
    repeater.DataSource = lst;
    repeater.DataBind();

    // test code
    MyControlType realItem1 = repeater.Items[0].Controls[1] as MyControlType;
    MyControlType realItem2 = repeater.Items[1].Controls[1] as MyControlType;
    MyControlType realItem3 = repeater.Items[2].Controls[1] as MyControlType;
    bool test1 = realItem1.IsRetained; // true (data == "item 1")
    bool test2 = realItem2.IsRetained; // false (data != "item 1")
    bool test3 = realItem3.IsRetained; // false (data != "item 1")
}

You can see we have expected results here.

afzalulh
  • 7,925
  • 2
  • 26
  • 37
  • Thanks, but as the control in question will be one of many in a Repeater control, I don't understand how having a single ViewState property would help. Yes, I could populate them in the ViewState in a slightly more complicated way, but I'm not even primarily concerned with persisting across postbacks in this example - just having simple properties successfully included when databinding. – chris4600 Dec 24 '13 at 04:48
  • Sorry, can't understand what you mean by "one of many". Each instance of the user control in repeater will use different ViewState. – afzalulh Dec 24 '13 at 05:01
  • Thanks, you are correct, I misinterpreted something. I may end up using something like this approach. – chris4600 Dec 24 '13 at 05:10
  • 1
    I think issue is when a instance of the control is created in repeater's IemDataBound, it will have default value of `IsRetained`, which is 'False' So, adding viewstate will not help. I will edit my answer. – afzalulh Dec 24 '13 at 05:18