private void createChildControlsAndWireUpEvents() { captionTable = TableOps.CreateUnderlyingTable(); captionTable.CssClass = "ewfStandardDynamicTableCaption"; captionTable.Visible = false; var row = new TableRow(); var captionCell = new TableCell(); captionCell.Controls.Add(captionStack = ControlStack.Create(false)); row.Cells.Add(captionCell); var actionLinksCell = new TableCell { CssClass = "ewfAddItemLink" }; actionLinksCell.Controls.Add(actionLinkStack = ControlStack.Create(false)); row.Cells.Add(actionLinksCell); captionTable.Rows.Add(row); Controls.Add(captionTable); table = TableOps.CreateUnderlyingTable(); Controls.Add(table); PreRender += ewfTable_PreRender; dataModifications = FormState.Current.DataModifications; }
void ControlTreeDataLoader.LoadData() { if (dateModificationMethod == null) { throw new ApplicationException("In order to place this calendar on a page, you must call SetParameters before the end of LoadData."); } buildNavigationBox(); // Begin drawing calendar var table = TableOps.CreateUnderlyingTable(); table.Attributes["class"] = "ewfMonthView ewfMonthViewCalendar"; base.Controls.Add(table); var headerRow = new TableRow(); foreach (var day in Enum.GetValues(typeof(DayOfWeek))) { headerRow.Cells.Add(new TableCell { Text = day.ToString(), CssClass = "commonHeader ewfDaysOfWeekHeader" }); } table.Rows.Add(headerRow); var localDate = IsTwoWeekCalendar ? date.WeekBeginDate() : new DateTime(date.Year, date.Month, 1).WeekBeginDate(); var endDrawingDate = IsTwoWeekCalendar ? localDate.AddDays(13) : new DateTime(date.Year, date.Month, 1).AddDays(DateTime.DaysInMonth(date.Year, date.Month) - 1); do { var row = new TableRow(); foreach (DayOfWeek dayOfWeek in Enum.GetValues(typeof(DayOfWeek))) { var cell = new TableCell { Text = " " }; if (IsTwoWeekCalendar || localDate.Date.Month.CompareTo(date.Date.Month) == 0) { if (daysOfMonthToCells.ContainsKey(localDate)) { cell = daysOfMonthToCells[localDate]; } if (daysOfMonthToolTips.ContainsKey(localDate)) { new ToolTip(daysOfMonthToolTips[localDate].Content, cell); } } cell.Attributes.Add("class", localDate.CompareTo(DateTime.Now.Date) == 0 ? "ewfToday" : localDate.Month == date.Month ? "ewfDay" : "ewfDaySpacer"); cell.Controls.AddAt(0, new Paragraph(localDate.Day.ToString().GetLiteralControl()) { CssClass = "dayLabel" }); row.Cells.Add(cell); localDate = localDate.AddDays(1); } table.Rows.Add(row); }while(localDate.CompareTo(endDrawingDate) <= 0); }
/// <summary> /// Creates a new instance of a Control Line with the given controls. /// </summary> public ControlLine(params Control[] controls) { var table = TableOps.CreateUnderlyingTable(); table.Rows.Add(row = new TableRow()); base.Controls.Add(table); AddControls(controls); VerticalAlignment = TableCellVerticalAlignment.NotSpecified; }
private void ewfTable_PreRender(object sender, EventArgs e) { // NOTE: This should all move to ControlTreeDataLoader.LoadData, but it can't right now because so many pages add table rows from PreRender. TableOps.AlternateRowColors(table, rowSetups); // NOTE: We should be able to get rid of this row hiding when we port everything over to use AddAllDataToTable. var dataRowIndex = 0; for (var rowIndex = 0; rowIndex < rowSetups.Count; rowIndex++) { table.Rows[rowIndex].Visible = dataRowIndex++ < CurrentDataRowLimit; } }
void ControlTreeDataLoader.LoadData() { if (hideIfEmpty && itemGroups.All(itemGroup => !itemGroup.Items.Any())) { Visible = false; return; } EwfTable.SetUpTableAndCaption(this, style, classes, caption, subCaption); var itemSetupLists = new[] { headItems }.Concat(itemGroups.Select(i => i.Items)).Select(i => i.Select(j => j.Setup.FieldOrItemSetup)); var allItemSetups = itemSetupLists.SelectMany(i => i).ToImmutableArray(); var columnWidthFactor = EwfTable.GetColumnWidthFactor(allItemSetups); foreach (var itemSetups in itemSetupLists.Where(i => i.Any())) { Controls.Add( new WebControl(HtmlTextWriterTag.Colgroup).AddControlsReturnThis(itemSetups.Select(i => EwfTable.GetColControl(i, columnWidthFactor)))); } var fields = EwfTable.GetFields(specifiedFields, headItems, itemGroups.SelectMany(i => i.Items)); var cellPlaceholderListsForItems = TableOps.BuildCellPlaceholderListsForItems( headItems.Concat(itemGroups.SelectMany(i => i.Items)).ToList(), fields.Count); // Pivot the cell placeholders from column primary into row primary format. var cellPlaceholderListsForRows = Enumerable.Range(0, fields.Count) .Select(field => Enumerable.Range(0, allItemSetups.Length).Select(item => cellPlaceholderListsForItems[item][field]).ToList()) .ToList(); var headRows = TableOps.BuildRows( cellPlaceholderListsForRows.Take(firstDataFieldIndex).ToList(), fields.Select(i => i.FieldOrItemSetup).ToImmutableArray(), null, allItemSetups, allItemSetups.Length, true); var bodyRows = TableOps.BuildRows( cellPlaceholderListsForRows.Skip(firstDataFieldIndex).ToList(), fields.Select(i => i.FieldOrItemSetup).ToImmutableArray(), false, allItemSetups, headItems.Count, true); // We can't easily put the head fields in thead because we don't have a way of verifying that cells don't cross between head and data fields. Controls.Add(new WebControl(HtmlTextWriterTag.Tbody).AddControlsReturnThis(headRows.Concat(bodyRows))); EwfTable.AssertAtLeastOneCellPerField(fields, cellPlaceholderListsForItems); }
private IEnumerable <Control> buildRows( IReadOnlyCollection <EwfTableItem> items, IReadOnlyCollection <EwfTableField> fields, bool?useContrastForFirstRow, bool useHeadCells, Func <EwfTableCell> itemActionCheckBoxCellGetter, Func <EwfTableCell> itemReorderingCellGetter, List <EwfTableItem> allVisibleItems) { // Assert that the cells in the list of items are valid and store a data structure for below. var cellPlaceholderListsForRows = TableOps.BuildCellPlaceholderListsForItems(items, fields.Count); // NOTE: Be sure to take check box and reordering columns into account. var rows = TableOps.BuildRows( cellPlaceholderListsForRows, items.Select(i => i.Setup.FieldOrItemSetup).ToImmutableArray(), useContrastForFirstRow, fields.Select(i => i.FieldOrItemSetup).ToImmutableArray(), useHeadCells ? fields.Count : 0, false); allVisibleItems.AddRange(items); return(rows); }
void ControlTreeDataLoader.LoadData() { using (MiniProfiler.Current.Step("EWF - Load table data")) { FormState.ExecuteWithDataModificationsAndDefaultAction( dataModifications, () => { if (hideIfEmpty && itemGroups.All(itemGroup => !itemGroup.Items.Any())) { Visible = false; return; } SetUpTableAndCaption(this, style, classes, caption, subCaption); var visibleItemGroupsAndItems = new List <Tuple <EwfTableItemGroup, IReadOnlyCollection <EwfTableItem> > >(); foreach (var itemGroup in itemGroups) { var visibleItems = itemGroup.Items.Take(CurrentItemLimit - visibleItemGroupsAndItems.Sum(i => i.Item2.Count)).Select(i => i()); visibleItemGroupsAndItems.Add(Tuple.Create <EwfTableItemGroup, IReadOnlyCollection <EwfTableItem> >(itemGroup, visibleItems.ToImmutableArray())); if (visibleItemGroupsAndItems.Sum(i => i.Item2.Count) == CurrentItemLimit) { break; } } var fields = GetFields(specifiedFields, headItems.AsReadOnly(), visibleItemGroupsAndItems.SelectMany(i => i.Item2)); if (!fields.Any()) { fields = new EwfTableField().ToCollection(); } addColumnSpecifications(fields); var allVisibleItems = new List <EwfTableItem>(); var itemLimitingUpdateRegionSet = new UpdateRegionSet(); var headRows = buildRows( getItemLimitingAndGeneralActionsItem(fields.Count, itemLimitingUpdateRegionSet).Concat(getItemActionsItem(fields.Count)).ToList(), Enumerable.Repeat(new EwfTableField(), fields.Count).ToArray(), null, false, null, null, allVisibleItems).Concat(buildRows(headItems, fields, null, true, null, null, allVisibleItems)).ToArray(); if (headRows.Any()) { Controls.Add(new WebControl(HtmlTextWriterTag.Thead).AddControlsReturnThis(headRows)); } var bodyRowGroupsAndRows = new List <Tuple <WebControl, ImmutableArray <Control> > >(); var updateRegionSetListsAndStaticRowGroupCounts = new List <Tuple <IReadOnlyCollection <UpdateRegionSet>, int> >(); for (var visibleGroupIndex = 0; visibleGroupIndex < visibleItemGroupsAndItems.Count; visibleGroupIndex += 1) { var groupAndItems = visibleItemGroupsAndItems[visibleGroupIndex]; var useContrastForFirstRow = visibleItemGroupsAndItems.Where((group, i) => i < visibleGroupIndex).Sum(i => i.Item2.Count) % 2 == 1; var groupBodyRows = buildRows(groupAndItems.Item2, fields, useContrastForFirstRow, false, null, null, allVisibleItems).ToImmutableArray(); var rowGroup = new WebControl(HtmlTextWriterTag.Tbody).AddControlsReturnThis( buildRows( groupAndItems.Item1.GetHeadItems(fields.Count), Enumerable.Repeat(new EwfTableField(), fields.Count).ToArray(), null, true, null, null, allVisibleItems).Concat(new NamingPlaceholder(groupBodyRows).ToCollection())); bodyRowGroupsAndRows.Add(Tuple.Create(rowGroup, groupBodyRows)); var cachedVisibleGroupIndex = visibleGroupIndex; EwfPage.Instance.AddUpdateRegionLinker( new LegacyUpdateRegionLinker( rowGroup, "tail", from region in groupAndItems.Item1.RemainingData.Value.TailUpdateRegions let staticRowCount = itemGroups[cachedVisibleGroupIndex].Items.Count - region.UpdatingItemCount select new LegacyPreModificationUpdateRegion(region.Sets, () => groupBodyRows.Skip(staticRowCount), staticRowCount.ToString), arg => groupBodyRows.Skip(int.Parse(arg)))); // If item limiting is enabled, include all subsequent item groups in tail update regions since any number of items could be appended. if (defaultItemLimit != DataRowLimit.Unlimited) { updateRegionSetListsAndStaticRowGroupCounts.Add( Tuple.Create <IReadOnlyCollection <UpdateRegionSet>, int>( groupAndItems.Item1.RemainingData.Value.TailUpdateRegions.SelectMany(i => i.Sets).ToImmutableArray(), visibleGroupIndex + 1)); } } Controls.Add(new NamingPlaceholder(bodyRowGroupsAndRows.Select(i => i.Item1))); if (defaultItemLimit != DataRowLimit.Unlimited) { var oldItemLimit = CurrentItemLimit; var lowerItemLimit = new Lazy <int>(() => Math.Min(oldItemLimit, CurrentItemLimit)); var itemLimitingTailUpdateRegionControlGetter = new Func <int, IEnumerable <Control> >( staticItemCount => { var rowCount = 0; for (var groupIndex = 0; groupIndex < bodyRowGroupsAndRows.Count; groupIndex += 1) { var rows = bodyRowGroupsAndRows[groupIndex].Item2; rowCount += rows.Length; if (rowCount < staticItemCount) { continue; } return(rows.Skip(rows.Length - (rowCount - staticItemCount)).Concat(bodyRowGroupsAndRows.Skip(groupIndex + 1).Select(i => i.Item1))); } return(ImmutableArray <Control> .Empty); }); EwfPage.Instance.AddUpdateRegionLinker( new LegacyUpdateRegionLinker( this, "itemLimitingTail", new LegacyPreModificationUpdateRegion( itemLimitingUpdateRegionSet.ToCollection(), () => itemLimitingTailUpdateRegionControlGetter(lowerItemLimit.Value), () => lowerItemLimit.Value.ToString()).ToCollection(), arg => itemLimitingTailUpdateRegionControlGetter(int.Parse(arg)))); } EwfPage.Instance.AddUpdateRegionLinker( new LegacyUpdateRegionLinker( this, "tail", from region in tailUpdateRegions.Select(i => new { sets = i.Sets, staticRowGroupCount = itemGroups.Count - i.UpdatingItemCount }) .Concat(updateRegionSetListsAndStaticRowGroupCounts.Select(i => new { sets = i.Item1, staticRowGroupCount = i.Item2 })) select new LegacyPreModificationUpdateRegion( region.sets, () => bodyRowGroupsAndRows.Skip(region.staticRowGroupCount).Select(i => i.Item1), region.staticRowGroupCount.ToString), arg => bodyRowGroupsAndRows.Skip(int.Parse(arg)).Select(i => i.Item1))); var itemCount = itemGroups.Sum(i => i.Items.Count); var itemLimitingRowGroup = new List <Control>(); if (CurrentItemLimit < itemCount) { var nextLimit = EnumTools.GetValues <DataRowLimit>().First(i => i > (DataRowLimit)CurrentItemLimit); var itemIncrementCount = Math.Min((int)nextLimit, itemCount) - CurrentItemLimit; var button = new PostBackButton( new TextActionControlStyle("Show " + itemIncrementCount + " more item" + (itemIncrementCount != 1 ? "s" : "")), usesSubmitBehavior: false, postBack: PostBack.CreateIntermediate( itemLimitingUpdateRegionSet.ToCollection(), id: PostBack.GetCompositeId(postBackIdBase, "showMore"), firstModificationMethod: () => EwfPage.Instance.PageState.SetValue(this, itemLimitPageStateKey, (int)nextLimit))); var item = new EwfTableItem(button.ToCell(new TableCellSetup(fieldSpan: fields.Count))); var useContrast = visibleItemGroupsAndItems.Sum(i => i.Item2.Count) % 2 == 1; itemLimitingRowGroup.Add( new WebControl(HtmlTextWriterTag.Tbody).AddControlsReturnThis( buildRows( item.ToCollection().ToList(), Enumerable.Repeat(new EwfTableField(), fields.Count).ToArray(), useContrast, false, null, null, allVisibleItems))); } Controls.Add( new NamingPlaceholder( itemLimitingRowGroup, updateRegionSets: itemLimitingUpdateRegionSet.ToCollection() .Concat( itemGroups.SelectMany(i => i.RemainingData.Value.TailUpdateRegions).ToImmutableArray().Concat(tailUpdateRegions).SelectMany(i => i.Sets)))); // Assert that every visible item in the table has the same number of cells and store a data structure for below. var cellPlaceholderListsForItems = TableOps.BuildCellPlaceholderListsForItems(allVisibleItems, fields.Count); if (!disableEmptyFieldDetection) { AssertAtLeastOneCellPerField(fields, cellPlaceholderListsForItems); } }); } }
/// <summary> /// Adds a row to this table. /// </summary> public void AddRow(RowSetup rowSetup, params EwfTableCell[] cells) { // If SetUpColumns was never called, implicitly set up the columns based on this first row. if (columnSetups == null) { columnSetups = cells.Select(c => new ColumnSetup()).ToList(); } rowSetups.Add(rowSetup); if (!rowSetup.IsHeader) { dataRowCount++; } var defaultCsvLine = cells.Select(cell => (cell as CellPlaceholder).SimpleText).ToList(); if (rowSetup.CsvLine == null) { rowSetup.CsvLine = defaultCsvLine; } // Verify that this row has the right number of cells. try { if (cells.Sum(c => c.Setup.FieldSpan) + previousRowColumnSpans.Sum(rcSpan => rcSpan.ColumnSpan) != columnSetups.Count) { throw new ApplicationException("Row to be added has the wrong number of cells."); } // Despite that it would make no sense to do this and all latest browsers will draw tables incorrectly when this happens, I cannot find official documentation // saying that it is wrong. NOTE: This check isn't as good as the logic we are going to add to EwfTableItemRemainingData (to ensure that the item has at // least one cell) because it doesn't catch a case like two cells that each have a row span greater than one and together span all columns. if (cells.Any(c => c.Setup.ItemSpan > 1 && c.Setup.FieldSpan == columnSetups.Count)) { throw new ApplicationException("Cell may not take up all columns and span multiple rows."); } } catch (ApplicationException e) { if (!ConfigurationStatics.IsDevelopmentInstallation) { TelemetryStatics.ReportError(e); } else { throw; } } foreach (var rowColumnSpanPair in previousRowColumnSpans) { rowColumnSpanPair.RowSpan--; } previousRowColumnSpans = (previousRowColumnSpans.Where(rowSpan => rowSpan.RowSpan > 0) .Concat( cells.Where(c => c.Setup.ItemSpan != 1) .Select(rowSpanCell => new RowColumnSpanPair { RowSpan = rowSpanCell.Setup.ItemSpan - 1, ColumnSpan = rowSpanCell.Setup.FieldSpan }))).ToList(); var cellPlaceHolders = new List <CellPlaceholder>(cells); TableOps.DrawRow(table, rowSetup, cellPlaceHolders, columnSetups, false); }