Вопрос

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!

Это было полезно?

Решение

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.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top