Нужно построить таблицу в 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;
}
}