Avatar billede Slettet bruger
01. juni 2009 - 20:58 Der er 6 kommentarer og
1 løsning

ASP repeater - Conditional alternate itemtemplate

Hejsa.

Jeg benytter en Asp:Repeater på en ASP.NET side med henholdsvis en ItemTemplate og en Alternate ItemTemplate, der udskriver tabel-rækker i henholdsvis hvid og grå farvet baggrund.
Dette fungerer fint, men min plan var at benytte det på en blog jeg er ved at lave - http://www.winfrastructure.dk/blog/ og her ville jeg gerne have, at de svar/kommentarer jeg selv går ind og skriver som svar på andres kommentarer til en artikel, bliver vist med en anden farve baggrund end den hvide eller grå baggrund.

Selve repeater er lavet på denne måde:

<asp:Repeater ID="repeater_Comments" runat="server">
    <HeaderTemplate><table class="blogCommentTable"></HeaderTemplate>
        <ItemTemplate>
            <tr>
                <td class="tdCommentName1"><%#DataBinder.Eval(Container.DataItem, "Name")%></td>
                <td class="tdCommentDate1"><%#DataBinder.Eval(Container.DataItem, "Date")%></td>
            </tr>
            <tr>
                <td class="tdComment1" colspan="2"><%#DataBinder.Eval(Container.DataItem, "Comment")%></td>
            </tr>
            <tr>
                <td class="tdCommentSpacer" colspan="2" style="padding: 0">&nbsp;</td>
            </tr>     
        </ItemTemplate>
        <AlternatingItemTemplate>
            <tr>
                <td class="tdCommentName2"><%#DataBinder.Eval(Container.DataItem, "Name")%></td>
                <td class="tdCommentDate2"><%#DataBinder.Eval(Container.DataItem, "Date")%></td>
            </tr>
            <tr>
                <td class="tdComment2" colspan="2"><%#DataBinder.Eval(Container.DataItem, "Comment")%></td>
            </tr>
            <tr>
                <td class="tdCommentSpacer" colspan="2" style="padding: 0">&nbsp;</td>
            </tr>     
        </AlternatingItemTemplate>
    <FooterTemplate></table></FooterTemplate>
</asp:Repeater>

Og metoden, der kaldes der genererer repeateren er skrevet på denne måde:

protected void DisplayComments()
    {
        // Hent alle kommentarer til dette blog-indlæg
        List<BlogEntryComment> commentList = BlogEntriesDB.GetComments(this.blogEntry.Id);
        if (commentList.Count > 0)
        {
            this.repeater_Comments.DataSource = commentList;
            this.repeater_Comments.DataBind();
        }
        else
        {
            this.header_Comments.Visible = false;
        }
    }

Repeateren databindes til en <List> i en metode der ser ud som:

[DataObjectMethod(DataObjectMethodType.Select)]
    public static List<BlogEntryComment> GetComments()
    {
        List<BlogEntryComment> blogCommentList = new List<BlogEntryComment>();
        IDbConnection connection = null;
        IDbCommand command = null;

        // Opret databaseadgang
        connection = DBFactory.GetDbConnection();
        command = connection.CreateCommand();

        command.CommandText = "SELECT Blog_Comments.Id, Blog_Comments.Date, Blog_Comments.Name, Blog_Comments.Comment, Blog_Comments.Admin, Blog_BlogEntries.Header";
        command.CommandText += " FROM Blog_Comments INNER JOIN Blog_BlogEntries ON Blog_Comments.BlogEntryId = Blog_BlogEntries.Id ORDER BY Blog_Comments.Id DESC";
        command.Connection.Open();

        BlogEntryComment blogEntryComment = null;
        IDataReader reader = command.ExecuteReader(CommandBehavior.CloseConnection);
        while (reader.Read())
        {
            blogEntryComment = new BlogEntryComment();
            blogEntryComment.Id = (int)reader["Id"];
            blogEntryComment.Date = (string)reader["Date"].ToString().Substring(0, 10);
            blogEntryComment.Name = (string)reader["Name"];
            blogEntryComment.Comment = (string)reader["Comment"];
            blogEntryComment.Admin = Convert.ToBoolean(reader["Admin"]);
            blogEntryComment.Header = (string)reader["Header"];
            blogCommentList.Add(blogEntryComment);
        }
        reader.Close();

        if (connection.State == ConnectionState.Open)
            command.Connection.Close();

        return blogCommentList;
    }

Da jeg allerede benytter en Alternate ItemTemplate, og heller ikke er klar over hvordan jeg i givet fald ville kune sætte en alternativ farve programmeringsmæssigt, er mit spørgsmål nu.

Hvordan vil jeg ud fra om en blogEntryComment, der er den objekt-type, der er i listen, der returneres til repeateren, har en Admin property der er true kunne lave endnu en alternativ farve i listen over kommentarer?
'Admin' sættes kun til true, hvis kommentaren er skrevet fra et administrativt site belligende bagved selve hjemmesiden og hvis denne er sat til true vil jeg gerne have at tabel-rækken er fx. gul eller orange...

Håber der er én der kan give en pointer i den rigtige retning.
Avatar billede keysersoze Guru
01. juni 2009 - 23:14 #1
Benyt eventen ItemCreated - her lidt pseudo-kode;

protected void rptTest_ItemCreated(object sender, RepeaterItemEventArgs e)
{
  if (e.Item.ItemType != ListViewItemType.EmptyItem)
  {
    yourobj yourvar = (yourobj)e.Item.DataItem;

    if (yourvar.tourtype == "compare")
    {
      ((Panel)this.rptTest.FindControl("etpanel")).BackColor = System.Drawing.Color.Red;
    }
  }
}

Dette kræver selvfølgelig at du har en control, fx et panel som i mit eksempel, du kan fange og give farven til.
Avatar billede Slettet bruger
02. juni 2009 - 11:33 #2
Nu ved jeg ikke om jeg skyder i blinde, men jeg er faktisk kommet en smule nærmere (tror jeg), i det jeg har ændret lidt på tingene.
I stedet for en generisk liste, returnerer jeg nu en IDataReader:

// ********************************************************************************************************
    // GetComments() - Henter alle kommentarer for et blog-indlæg
    // ********************************************************************************************************
    public static IDataReader GetComments(int blogEntryId)
    {
        List<BlogEntryComment> blogCommentList = new List<BlogEntryComment>();
        IDbConnection connection = null;
        IDbCommand command = null;

        // Opret databaseadgang
        connection = DBFactory.GetDbConnection();
        command = connection.CreateCommand();

        command.CommandText = "SELECT * FROM Blog_Comments WHERE BlogEntryId = '" + blogEntryId + "' ORDER BY Date ASC";
        command.Connection.Open();
        IDataReader reader = command.ExecuteReader(CommandBehavior.CloseConnection);

        return reader;
    }

Der hentes ind i metoden i min CodeBehind fil:

    // ***************************************************************************************************************
    // DisplayBlogEntriesForCategory - Henter alle indlæg for kategori og viser dem i højre side
    // ***************************************************************************************************************
    protected void DisplayComments()
    {
        // Hent alle kommentarer til dette blog-indlæg
        IDataReader commentList = BlogEntriesDB.GetComments(this.blogEntry.Id);
        if (commentList.FieldCount > 0)
        {
            this.repeater_Comments.DataSource = commentList;
            this.repeater_Comments.DataBind();
        }
        else
        {
            this.header_Comments.Visible = false;
        }
    }

Så har jeg tilføjet en EventHandler kaldet void repeater_Comments_ItemDataBound:

protected void repeater_Comments_ItemDataBound(object sender, RepeaterItemEventArgs e)
    {
        if (e.Item.ItemType == ListItemType.Item || e.Item.ItemType == ListItemType.AlternatingItem)
        {
            IDataRecord record = (IDataRecord)e.Item.DataItem;
            if (Convert.ToBoolean(record["Admin"]))
            {

            }
        }
    }

Hvor det er lykkedes mig at lave selve valideringen på om der er tale om et 'Admin-indlæg' og udskrive data afhængigt af om flaget er sat eller ej.
Dette virker med en Response.Write, men jeg er så kørt fast herfra.

Kan det lade sig gøre at lave noget logik indenfor denne eventhandler, altså:

if (e.Item.ItemType == ListItemType.Item || e.Item.ItemType == ListItemType.AlternatingItem)
        {
            IDataRecord record = (IDataRecord)e.Item.DataItem;
            if (Convert.ToBoolean(record["Admin"]))
            {

            }
        }

Hvor egenskaben BackGroundColor eller lignende sættes på den aktuelle row?
Avatar billede Slettet bruger
02. juni 2009 - 11:37 #3
Se venligst bort fra metodernes beskrivelser. Der er kopieret og pastet en del i de sene timer og jeg kan se at de overhovedet ikke matcher det der sker i metoderne :-)
Avatar billede Slettet bruger
02. juni 2009 - 14:30 #4
Jeg fik løst det med følgende tilføjelse til min repeater_Comments_ItemDataBound eventhandler:

protected void repeater_Comments_ItemDataBound(object sender, RepeaterItemEventArgs e)
    {
        if (e.Item.ItemType == ListItemType.Item || e.Item.ItemType == ListItemType.AlternatingItem)
        {
            IDataRecord record = (IDataRecord)e.Item.DataItem;
            if (Convert.ToBoolean(record["Admin"]))
            {
                System.Web.UI.HtmlControls.HtmlTableCell tdCommentName = (System.Web.UI.HtmlControls.HtmlTableCell)e.Item.FindControl("tdCommentName");
                tdCommentName.Attributes.CssStyle.Value = "background-color: #99CC99; color: #ffffff";

                System.Web.UI.HtmlControls.HtmlTableCell tdCommentDate = (System.Web.UI.HtmlControls.HtmlTableCell)e.Item.FindControl("tdCommentDate");
                tdCommentDate.Attributes.CssStyle.Value = "background-color: #99CC99; color: #ffffff";

                System.Web.UI.HtmlControls.HtmlTableCell tdComment = (System.Web.UI.HtmlControls.HtmlTableCell)e.Item.FindControl("tdComment");
                tdComment.Attributes.CssStyle.Value = "background-color: #99CC99; color: #ffffff";
            }
        }
    }
Avatar billede Slettet bruger
02. juni 2009 - 14:33 #5
Har selvfølgelig givet mine <td> et id og et runat="server", så de kan refereres fra CodeBehind.
Avatar billede keysersoze Guru
02. juni 2009 - 17:51 #6
jamen - tak for hjælpen...
Avatar billede Slettet bruger
02. juni 2009 - 18:41 #7
@keysersoze. Sorry hvis du føler du ikke får kredit for din kommentar. Jeg takker for dit input, som jeg desværre aldrig nåede at forholde mig rigtigt til.
Jeg kunne godt se der var en sammenhæng mellem dit forslag og den løsning jeg selv googlede mig frem til, specielt med hensyn til e.Item.ItemType == ListItemType.Item || e.Item.ItemType == ListItemType.AlternatingItem, men igen, jeg fandt den på technet.com og da det er to vidt forskellige events vi forholder os til, arbejdede jeg bevidst ikke videre med det du kom med.

Men igen. Tak for dit forslag!
Avatar billede Ny bruger Nybegynder

Din løsning...

Tilladte BB-code-tags: [b]fed[/b] [i]kursiv[/i] [u]understreget[/u] Web- og emailadresser omdannes automatisk til links. Der sættes "nofollow" på alle links.

Loading billede Opret Preview
Kategori
Kurser inden for grundlæggende programmering

Log ind eller opret profil

Hov!

For at kunne deltage på Computerworld Eksperten skal du være logget ind.

Det er heldigvis nemt at oprette en bruger: Det tager to minutter og du kan vælge at bruge enten e-mail, Facebook eller Google som login.

Du kan også logge ind via nedenstående tjenester