User Control Inside Repeater

耗尽温柔 提交于 2020-01-10 08:55:25

问题


I have a UserControl inside a repeater. The repeater's datasource is from SQL Server.

User Control's .cs - MoviePanel.ascx.cs:


public int myMovieID { get; set; }
public string myMovieName { get; set; }
public string myMovieDescription { get; set; }

protected void Page_Load(object sender, EventArgs e)
{
   MovieIDLbl.Text = myMovieID.ToString();
   MovieNameLbl.Text = myMovieName;
   DescriptionLbl.Text = myMovieDescription;
}

ASPX Page:


<asp:Repeater ID="Repeater1" DataSourceID="ListOfMoviesDS" runat="server">
    <ItemTemplate>
        <uc1:MovieDetailPanel runat="server" myMovieID='<%# Eval("MovieID") %>' 
           myMovieName='<%# Eval("movieName") %>' 
                myMovieDescription='<%# Eval("movieDescription") %>' 
                id="MovieDetailPanel1" />

        <asp:Label ID="Label1" runat="server" 
              Text='<%# Eval("MovieID") %>'></asp:Label>
        <asp:Label ID="Label2" runat="server" 
              Text='<%# Eval("movieName") %>'></asp:Label>
        <asp:Label ID="Label3" runat="server" 
             Text='<%# Eval("movieDescription") %>'></asp:Label>
    </ItemTemplate>
</asp:Repeater>

Here something very strange happens. The values are not getting passed to the UserControl. However, if I place Labels below the usercontrol and set text with Eval() it works. You might think the usercontrol might be the problem. But if I manually type something, say in place of <%# Eval("movieName") %> it gets passed to the user control and gets displayed.

I have NO CLUE! If the problem is with Eval() Labels should not get the text as well. Or if the problem is with the UserControl my manual text shouldn't get passed. I have no idea why Eval()'s values is not reaching the UserControl.


回答1:


Your code is working fine; I tested it (see the bottom of the page). The worst case you can try assigning those value inside ItemDataBound event.

<asp:Repeater ID="Repeater1" runat="server" OnItemDataBound="Repeater1_ItemDataBound">
    <ItemTemplate>
        <uc1:MoviePanel runat="server" id="MovieDetailPanel1" />
    </ItemTemplate>
</asp:Repeater>

public class Movie
{
    public int MovieID { get; set; }
    public string MovieName { get; set; }
    public string MovieDescription { get; set; }
}

protected void Page_Load(object sender, EventArgs e)
{
    if (!IsPostBack)
    {
        Repeater1.DataSource = new List<Movie>
        {
            new Movie {MovieID = 1, MovieName = "One", MovieDescription = "One hundred"},
            new Movie {MovieID = 2, MovieName = "Two", MovieDescription = "Two hundreds"},
            new Movie {MovieID= 3, MovieName = "Three", MovieDescription = "Three hundreds"},
        };
        Repeater1.DataBind();
    }
}

protected void Repeater1_ItemDataBound(object sender, RepeaterItemEventArgs e)
{
    if (e.Item.ItemType == ListItemType.Item ||
        e.Item.ItemType == ListItemType.AlternatingItem)
    {
        var movie = e.Item.DataItem as Movie;

        var control = e.Item.FindControl("MovieDetailPanel1") as MoviePanel;
        control.myMovieID = movie.MovieID;
        control.myMovieDescription = movie.MovieDescription;
        control.myMovieName = movie.MovieName;
    }
}

Here is how I test your original question

<%@ Page Language="C#" AutoEventWireup="true" CodeBehind="WebForm1.aspx.cs" Inherits="WebDemo.WebForm1" %>

<%@ Register src="MoviePanel.ascx" tagname="MoviePanel" tagprefix="uc1" %>

<!DOCTYPE html>

<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
    <title></title>
</head>
<body>
    <form id="form1" runat="server">
        <asp:Repeater ID="Repeater1" runat="server">
            <ItemTemplate>
                <uc1:MoviePanel runat="server" mymovieid='<% #Eval("MovieID") %>'
                    mymoviename='<% #Eval("movieName") %>'
                    mymoviedescription='<% #Eval("movieDescription") %>'
                    id="MovieDetailPanel1" />
            </ItemTemplate>
        </asp:Repeater>
    </form>
</body>
</html>


namespace WebDemo
{
    public partial class WebForm1 : System.Web.UI.Page
    {
        public class Movie
        {
            public int MovieID { get; set; }
            public string MovieName { get; set; }
            public string MovieDescription { get; set; }
        }

        protected void Page_Load(object sender, EventArgs e)
        {
            if (!IsPostBack)
            {
                Repeater1.DataSource = new List<Movie>
                {
                    new Movie {MovieID = 1, MovieName = "One", MovieDescription = "One hundred"},
                    new Movie {MovieID = 2, MovieName = "Two", MovieDescription = "Two hundreds"},
                    new Movie {MovieID= 3, MovieName = "Three", MovieDescription = "Three hundreds"},
                };
                Repeater1.DataBind();
            }
        }
    }
}

<%@ Control Language="C#" AutoEventWireup="true"
    CodeBehind="MoviePanel.ascx.cs" Inherits="WebDemo.MoviePanel" %>

<p>
    <strong>Inside Control</strong>:
    <asp:Label ID="MovieIDLbl" runat="server" />
    <asp:Label ID="MovieNameLbl" runat="server" />
    <asp:Label ID="DescriptionLbl" runat="server" />
</p>

namespace WebDemo
{
    public partial class MoviePanel : System.Web.UI.UserControl
    {
        public int myMovieID { get; set; }
        public string myMovieName { get; set; }
        public string myMovieDescription { get; set; }

        protected void Page_Load(object sender, EventArgs e)
        {
            MovieIDLbl.Text = myMovieID.ToString();
            MovieNameLbl.Text = myMovieName;
            DescriptionLbl.Text = myMovieDescription;
        }
    }
}



回答2:


here is one way, doing it all in the code behind. I can't say this is best practice, but it's clean. You use the ItemDataBind event, cast the item to what you want, datatable, whatever, then create a new instance of the user control and add it to the repeater's control collection

Page source

public partial class _Default : Page
{
    protected void Page_Load(object sender, EventArgs e)
    {
        var myList = new List<string>() { "one", "two", "three" };
        myRepeater.DataSource = myList;
        myRepeater.DataBind();
    }

    public void R1_ItemDataBound(Object Sender, RepeaterItemEventArgs e)
    {
        var items = (string)e.Item.DataItem;
        var newcontrol = (WebUserControl1)Page.LoadControl("~/WebUserControl1.ascx");
        newcontrol.myTest = items;
        myRepeater.Controls.Add(newcontrol);           
    }   
}

Page html

 <asp:Repeater ID="myRepeater"  runat="server" OnItemDataBound="R1_ItemDataBound">
    <ItemTemplate>

    </ItemTemplate>
</asp:Repeater>

user control

<h1 id="myLabel" runat="server"></h1>

and

public partial class WebUserControl1 : System.Web.UI.UserControl
{
    public string myTest { get; set; }
    protected void Page_Load(object sender, EventArgs e)
    {
        myLabel.InnerText = myTest;
    }
}


来源:https://stackoverflow.com/questions/20136479/user-control-inside-repeater

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!