Нужно построить таблицу в 3 столбца

Изменить для ясности: я знаю, что код имеет 2 столбца, один для заголовка и один для даты, я пытаюсь изменить код, чтобы он отображал 3 события в строке.

Я новичок в разработке и пытаюсь взять элемент управления ASP, используемый на веб-сайте Sitefinity 6.1, который в настоящее время берет данные из нашей базы данных SQL и выводит их в один столбец, а вместо этого выводит данные в 3 столбца.

.Ascx выглядит так

<div style="margin:10px">
    <asp:MultiView ID="mvEvents" runat="server" ActiveViewIndex="0">
        <asp:View ID="viewDefault" runat="server">
            <asp:Table ID="tblEvents" runat="server" CellPadding="5">
            </asp:Table>
        </asp:View>
        <asp:View ID="viewList" runat="server">
            <asp:Table ID="tblEventsList" runat="server" CellPadding="5">
            </asp:Table>
        </asp:View>
    </asp:MultiView>
</div>

Части PageLoad и BuildEvents кода.ascx.cs выглядят так

protected void Page_Load(object sender, EventArgs e)
    {
        try
        {
            CalendarDataContext db = new CalendarDataContext();

            var evt = db.CalendarEvents(NumberToDisplay, Department);

            foreach (CalendarEventsResult Evt in evt)
            {
                if (Department == "List")
                {
                    BuildEventsList(Evt.event_name, Evt.event_start_date, Evt.event_idn, Evt.information_id);
                }
                else
                {
                    BuildEvents(Evt.event_name, Evt.event_start_date, Evt.event_idn, Evt.information_id);
                }
            }
            return;
        }
        catch(Exception ex)
        {
        }
    }

    protected void BuildEvents(string EvtTitle, DateTime EvtStart, int EvtIdn, int EvtInfoIdn)
    {
        //EvtInfoIdn shows Event Description without location.  EvtInfoIdn - 1 shows location information. changing the href to eventInfoId
        int EvtInfoId = EvtInfoIdn - 1;


        TableRow tr = new TableRow();
        tr.VerticalAlign = VerticalAlign.Top;
        tr.HorizontalAlign = HorizontalAlign.Center;
        TableCell tcTitle = new TableCell();
        TableCell tcStart = new TableCell();
        StringBuilder sb = new StringBuilder();
        sb.AppendLine(ShortMonth(EvtStart.Month));
        sb.AppendLine(EvtStart.Day.ToString());

        tr.VerticalAlign = VerticalAlign.Bottom;
        tr.Height = Unit.Pixel(80);

        Literal litDate = new Literal();
        litDate.Text = "<div class='EventDate'>" + sb.ToString() + "</div>";
        tcStart.Controls.Add(litDate);

        Literal litTitle = new Literal();
        litTitle.Text = @"<div class='EventTitle'><a style='text-decoration:none;' href='http://events.website.edu/EventList.aspx?view=EventDetails&eventidn=" + EvtIdn.ToString().Trim() + "&information_id=" + EvtInfoId + "&type=&rss=rss'>";
        litTitle.Text = litTitle.Text + EvtTitle + "</a></div>";
        tcTitle.Controls.Add(litTitle);

        tr.Cells.Add(tcStart);
        tr.Cells.Add(tcTitle);

        tblEvents.Rows.Add(tr);
    }

Я попытался добавить атрибут ColumnSpan = "3" в файл ascx, а также попытался добавить ColumnSpan к tcStart и tcTitle в файле cs, в дополнение к попытке перепроектировать ascx в режиме разработки, и ничего из этого не сработало, Я понимаю, что это, вероятно, легко исправить, но я новичок в программировании на C#. Я ценю любую помощь, оказанную.

1 ответ

Решение

Попробуйте следующее: nb Я не смог протестировать полностью, так как я не смоделировал ваши классы на заказ, например CalendarDataContext,

Основная предпосылка заключается в том, что CalandarEvents сбор обрабатывается партиями по 3 (или по любому числу, которое вы выбираете), и что BuildEvents Теперь метод разбит на более мелкие части, каждая из которых несет свою ответственность, что должно помочь в дальнейшем обслуживании.

    protected void Page_Load(object sender, EventArgs e)
    {
        try
        {
            CalendarDataContext db = new CalendarDataContext();
            var evt = db.CalendarEvents(NumberToDisplay, Department);

            if (Department == "List")
            {
                foreach (CalendarEventsResult cer in evt)
                {
                    BuildEventsList(cer.event_name, cer.event_start_date, cer.event_idn, cer.information_id);
                }
            }
            else
            {
                // Depending what type evt is may depend on how to convert to the List.
                // This assumes that it supports IEnumerable (like DataTable) 
                List<CalendarEventsResult> events = evt.AsEnumerable().ToList();

                // Rather than hard-coding, read this from config or database 
                // to allow easier changing to a different number of events per row?
                int numberOfEventsPerRow = 3;

                // loop increments in steps of 3 (numberOfEventsPerRow)
                for (int rowNumber = 0; rowNumber < events.Count; rowNumber += numberOfEventsPerRow)
                {
                    // use Linq to pick out the subset of Events to process
                    List<CalendarEventsResult> queryEvents = events
                        .Skip(numberOfEventsPerRow * rowNumber)
                        .Take(numberOfEventsPerRow).ToList<CalendarEventsResult>();

                    // Build a row using that subset
                    TableRow tr = buildRow(queryEvents, numberOfEventsPerRow);
                    // Add it to the table
                    tblEvents.Rows.Add(tr);
                }
            }
        }
        catch (Exception ex)
        {
            // this just suppresses any exceptions. Better to fix issues at source.
        }
    }

    private TableRow buildRow(List<CalendarEventsResult> events, int eventsPerRow)
    {
        TableRow tr = new TableRow();

        // Can these be added to CSS?
        tr.HorizontalAlign = HorizontalAlign.Center;
        tr.VerticalAlign = VerticalAlign.Bottom;
        tr.Height = Unit.Pixel(80);

        TableCell tc;

        // for our event subset, build a pair of cells for each Event,
        // adding them to a row
        foreach (var evt in events)
        {
            tc = BuildEventDate(evt);
            tr.Cells.Add(tc);
            tc = BuildEventTitle(evt);
            tr.Cells.Add(tc);
        }

        // If we're dealing with a partial row, i.e. only 1 or 2 Events,
        // pad the row with empty cells.
        if (events.Count < eventsPerRow)
        {
            tc = BuildEmptyCell(eventsPerRow - events.Count);
            tr.Cells.Add(tc);
        }

        return tr;
    }

    private TableCell BuildEventDate(CalendarEventsResult evt)
    {
        TableCell tc = new TableCell();

        Literal litDate = new Literal();
        //String.Format should suffice c.f. StringBuilder
        litDate.Text = String.Format("<div class='EventDate'>{0}{1}</div>", ShortMonth(evt.Month), evt.Day.ToString());
        tc.Controls.Add(litDate);

        return tc;
    }

    private TableCell BuildEventTitle(CalendarEventsResult evt)
    {
        TableCell tc = new TableCell();
        int evtInfoId = evt.information_id - 1;

        Literal litTitle = new Literal();
        // n.b. hard-coded URL doesn't look good for ease of maintenance (move to config or CalendarEventsResult?)
        litTitle.Text = String.Format(@"<div class='EventTitle'><a style='text-decoration:none;' href='http://events.website.edu/EventList.aspx?view=EventDetails&eventidn={0}&information_id={1}&type=&rss=rss'>{2}</a></div>", 
            evt.event_idn.ToString().Trim(), evtInfoId, evt.event_name);
        tc.Controls.Add(litTitle);

        return tc;
    }

    private TableCell BuildEmptyCell(int numberOfEvents)
    {
        // Define as const rather than having unexplained "2" hard-coded.
        const int spanPerEvent = 2;

        TableCell tc = new TableCell();
        tc.ColumnSpan = spanPerEvent * numberOfEvents;
        tc.Text = "";
        return tc;
    }
}
Другие вопросы по тегам