public DtoCellViewModel(IViewModelDependencies dependencies, IZetboxContext dataCtx, DtoTableViewModel parent, IFileOpener fileOpener, ITempFileService tmpService, DtoRowViewModel row, DtoColumnViewModel column, GuiGridLocationAttribute location, ViewModel value, object debugInfo) : base(dependencies, dataCtx, parent, fileOpener, tmpService, debugInfo) { this.Parent = parent; this.Row = row; this.Column = column; this._location = location; this._value = value; }
private void ExportTable(DtoTableViewModel dto) { var tmpFile = _tmpService.CreateWithExtension("_Export.csv"); // Excel can't open two files with the same name, located in another folder! StreamWriter sw; // http://stackoverflow.com/questions/545666/how-to-translate-ms-windows-os-version-numbers-into-product-names-in-net if (Environment.OSVersion.Platform == PlatformID.Win32NT && Environment.OSVersion.Version.Major <= 5) // assuming Windox XP or lower sw = new StreamWriter(tmpFile, false, Encoding.Default); else sw = new StreamWriter(tmpFile, false, Encoding.UTF8); // use this constructor to ensure BOM using (sw) { // Header sw.WriteLine(string.Join(";", dto.Columns.Select(i => "\"" + i.Title.Replace("\"", "\"\"") + "\"").ToArray())); // Data var maxRow = dto.Rows.Count - 1; var maxCol = dto.Columns.Count - 1; for (int rowIdx = 0; rowIdx <= maxRow; rowIdx++) { var myRow = dto.Rows[rowIdx]; for (int colIdx = 0; colIdx <= maxCol; colIdx++) { var myCol = dto.Columns[colIdx]; var myCell = dto.Cells.SingleOrDefault(cell => cell.Row == myRow && cell.Column == myCol); if (myCell != null) { string val = myCell.Value.ToString(); if (val != null) { var needsQuoting = val.IndexOfAny(new[] { ';', '\n', '\r', '"' }) >= 0; if (needsQuoting) { val = val.Replace("\"", "\"\""); val = "\"" + val + "\""; } sw.Write(val); } } if (colIdx < maxCol) { sw.Write(";"); } else { sw.WriteLine(); } } } } _fileOpener.ShellExecute(tmpFile); }
private void AppendAsTable(DocumentListState dls, DtoTableViewModel dto) { dls.ForceOrientation(Orientation.Landscape); dls.AddHeading(dto.Title, dto.DebugInfo); dls.CurrentTable = dls.CurrentSection.AddTable(); dls.CurrentTable.KeepTogether = true; var maxCol = dto.Columns.Count - 1; for (int i = 0; i <= maxCol; i++) { dls.CurrentTable.AddColumn(); } dls.CurrentTable.Columns[0].Width = "4cm"; var header = dls.CurrentTable.AddRow(); for (int i = 0; i <= maxCol; i++) { header.Cells[i].AddParagraph(dto.Columns[i].Title); header.Cells[i].Format.Alignment = ParagraphAlignment.Center; } var maxRow = dto.Rows.Count - 1; for (int rowIdx = 0; rowIdx <= maxRow; rowIdx++) { var row = dls.CurrentTable.AddRow(); if (rowIdx % 2 == 0) { row.Format.Shading.Color = Colors.LightGray; } var myRow = dto.Rows[rowIdx]; for (int colIdx = 0; colIdx <= maxCol; colIdx++) { var myCol = dto.Columns[colIdx]; var myCell = dto.Cells.SingleOrDefault(cell => cell.Row == myRow && cell.Column == myCol); if (myCell != null) { row.Cells[colIdx].AddParagraph(myCell.Value.ToString()); if (myCell.Value is DtoValueViewModel) { row.Cells[colIdx].Format.Alignment = ConvertParagraphAlignment(((DtoValueViewModel)myCell.Value).ValueAlignment); } } } } dls.AddDescription(dto.Description); dls.CurrentTable = null; }
private static void InitGrid(Grid grid, DtoTableViewModel vm) { if (vm != null && grid != null) { grid.RowDefinitions.Clear(); grid.ColumnDefinitions.Clear(); foreach (var row in vm.Rows) { grid.RowDefinitions.Add(new RowDefinition()); } foreach (var col in vm.Columns) { grid.ColumnDefinitions.Add(new ColumnDefinition() { SharedSizeGroup = "col" + col.Column.ToString() }); } grid.InvalidateArrange(); grid.UpdateLayout(); } }
public DtoRowViewModel(IViewModelDependencies dependencies, IZetboxContext dataCtx, DtoTableViewModel parent, IFileOpener fileOpener, ITempFileService tmpService, int rowIdx, object debugInfo) : base(dependencies, dataCtx, parent, fileOpener, tmpService, debugInfo) { this.Parent = parent; this._row = rowIdx; }
private void AppendAsTable(DocumentListState dls, DtoTableViewModel dto) { dls.ForceOrientation(Orientation.Landscape); dls.AddHeading(dto.Title, dto.DebugInfo); dls.CurrentTable = dls.CurrentSection.AddTable(); dls.CurrentTable.KeepTogether = true; var maxCol = dto.Columns.Count - 1; for (int i = 0; i <= maxCol; i++) { dls.CurrentTable.AddColumn(); } dls.CurrentTable.Columns[0].Width = "4cm"; var header = dls.CurrentTable.AddRow(); for (int i = 0; i <= maxCol; i++) { header.Cells[i].AddParagraph(dto.Columns[i].Title); header.Cells[i].Format.Alignment = ParagraphAlignment.Center; } var maxRow = dto.Rows.Count - 1; for (int rowIdx = 0; rowIdx <= maxRow; rowIdx++) { var row = dls.CurrentTable.AddRow(); if (rowIdx % 2 == 0) row.Format.Shading.Color = Colors.LightGray; var myRow = dto.Rows[rowIdx]; for (int colIdx = 0; colIdx <= maxCol; colIdx++) { var myCol = dto.Columns[colIdx]; var myCell = dto.Cells.SingleOrDefault(cell => cell.Row == myRow && cell.Column == myCol); if (myCell != null) { row.Cells[colIdx].AddParagraph(myCell.Value.ToString()); if (myCell.Value is DtoValueViewModel) row.Cells[colIdx].Format.Alignment = ConvertParagraphAlignment(((DtoValueViewModel)myCell.Value).ValueAlignment); } } } dls.AddDescription(dto.Description); dls.CurrentTable = null; }
/// <summary> /// Arranges the contained Objects in a grid. Use GridLocation to specify where /// </summary> public static DtoTableViewModel BuildGridFrom(object root, PropertyInfo parentProp, object dto, IViewModelDependencies dependencies, IZetboxContext dataCtx, ViewModel parent, IFileOpener fileOpener, ITempFileService tmpService) { if (dto == null) { return(null); } var debugInfo = parentProp == null ? string.Format("topGrid:{0}", dto.GetType()) : string.Format("grid:{0}.{1} = {2}", parentProp.DeclaringType, parentProp.Name, dto.GetType()); var result = new DtoTableViewModel(dependencies, dataCtx, parent, fileOpener, tmpService, debugInfo) { IsDataTable = false, Title = ExtractTitle(parentProp, dto), Description = ExtractDescription(parentProp, dto), Background = ExtractBackground(parentProp, dto), Formatting = ExtractFormatting(parentProp, dto), IsPrintableRoot = ExtractIsPrintableRoot(parentProp, dto), Root = root, Data = dto, }; // TODO: add description var cells = new Dictionary <GuiGridLocationAttribute, ViewModel>(); if (typeof(IEnumerable).IsAssignableFrom(dto.GetType())) { var propertyMsg = parentProp == null ? string.Empty : string.Format(" contained in property {0}.{1}", parentProp.DeclaringType.Name, parentProp.Name); Logging.Client.WarnFormat("Unable to format a list from dto '{0}' of type '{1}'{2}", dto, dto.GetType().Name, propertyMsg); } else { var dataProps = new List <PropertyInfo>(); var percentProps = new Dictionary <string, PropertyInfo>(); ExtractProps(dto.GetType(), dataProps, percentProps); if (percentProps.Count != 0) { // TODO: fail: cannot display in grid? } foreach (var prop in dataProps) { var value = BuildFrom(root, prop, dto.GetPropertyValue <object>(prop.Name), dependencies, dataCtx, result, fileOpener, tmpService); if (value == null) { continue; // do not add without content } // struct initialises to (0,0) by default var gridLocation = prop.GetCustomAttributes(false) .OfType <GuiGridLocationAttribute>() .Single(); // TODO: avoid silent overwriting /* * TODO: might want to consider automatic appending? * That is, given a class with five properties that should be arranged * * A | B | C * D | E | - * * specify * * [GridRow(0)] * int A { get; set; } * int B { get; set; } * int C { get; set; } * [GridRow(1)] * int D { get; set; } * int E { get; set; } * * or even only [GridRowBreak] on D? */ cells[gridLocation] = value; } } var allRows = new Dictionary <int, DtoRowViewModel>(); for (int i = cells.Keys.Select(k => k.Row).Max(); i >= 0; i--) { allRows[i] = new DtoRowViewModel(dependencies, dataCtx, result, fileOpener, tmpService, i, string.Format("gridrow:{0}.[{1}]", dto.GetType(), i)); } var allColumns = new Dictionary <int, DtoColumnViewModel>(); for (int i = cells.Keys.Select(k => k.Column).Max(); i >= 0; i--) { allColumns[i] = new DtoColumnViewModel(dependencies, dataCtx, result, fileOpener, tmpService, i, string.Format("gridcolum:{0}.[][{1}]", dto.GetType(), i)); } foreach (var kvp in cells) { result.Cells.Add(new DtoCellViewModel(dependencies, dataCtx, result, fileOpener, tmpService, allRows[kvp.Key.Row], allColumns[kvp.Key.Column], kvp.Key, kvp.Value, string.Format("gridcell[{0}][{1}]", kvp.Key.Row, kvp.Key.Column))); } allRows.Values.ForEach(result.Rows.Add); allColumns.Values.ForEach(result.Columns.Add); return(result); }
/// <summary> /// Creates a table out of a list of DTOs /// </summary> public static DtoTableViewModel BuildTableFrom(object root, PropertyInfo parentProp, object dto, IViewModelDependencies dependencies, IZetboxContext dataCtx, ViewModel parent, IFileOpener fileOpener, ITempFileService tmpService) { if (dto == null) { return(null); } // skip XmlDictionary to its values if (dto.GetType().HasGenericDefinition(typeof(XmlDictionary <,>))) { dto = dto.GetPropertyValue <object>("Values"); } var debugInfo = parentProp == null ? string.Format("topTable: {0}", dto.GetType()) : string.Format("table:{0}.{1} = {2}", parentProp.DeclaringType, parentProp.Name, dto.GetType()); var result = new DtoTableViewModel(dependencies, dataCtx, parent, fileOpener, tmpService, debugInfo) { IsDataTable = true, Title = ExtractTitle(parentProp, dto), Description = ExtractDescription(parentProp, dto), Background = ExtractBackground(parentProp, dto), AlternateBackground = ExtractAlternateBackground(parentProp, dto), Formatting = ExtractFormatting(parentProp, dto), IsPrintableRoot = ExtractIsPrintableRoot(parentProp, dto), Root = root, Data = dto, }; var dataProps = new List <PropertyInfo>(); var percentProps = new Dictionary <string, PropertyInfo>(); ExtractProps(dto.GetType().FindElementTypes().SingleOrDefault(t => t != typeof(object)) ?? dto.GetType(), dataProps, percentProps); var allColumns = new Dictionary <PropertyInfo, DtoColumnViewModel>(); int columnIdx = 0; foreach (var prop in dataProps) { var column = new DtoColumnViewModel(dependencies, dataCtx, result, fileOpener, tmpService, columnIdx, string.Format("column:{0}.{1}", dto.GetType(), prop.Name)) { Title = ExtractTitle(prop, null), Description = ExtractDescription(prop, null), Background = ExtractBackground(prop, null) }; allColumns[prop] = column; columnIdx += 1; result.Columns.Add(column); } int rowIdx = 0; foreach (var line in (IEnumerable)dto) { var row = new DtoRowViewModel(dependencies, dataCtx, result, fileOpener, tmpService, rowIdx, string.Format("row:{0}[{1}]", dto.GetType(), rowIdx)); if (rowIdx % 2 == 0) { row.Background = result.AlternateBackground; } result.Rows.Add(row); columnIdx = -1; foreach (var prop in dataProps) { var propName = prop.Name; columnIdx += 1; var viewModel = BuildFrom(root, prop, line.GetPropertyValue <object>(propName), dependencies, dataCtx, row, fileOpener, tmpService); if (viewModel == null) { continue; // do not add cell without content } viewModel.Title = null; // do not display title in table var valueModel = viewModel as DtoValueViewModel; if (valueModel != null && percentProps.ContainsKey(propName)) { valueModel.AlternateRepresentation = string.Format("{0:0.00} %", 100 * Convert.ToDouble(dto.GetPropertyValue <object>(percentProps[propName].Name))); valueModel.AlternateRepresentationAlignment = ContentAlignment.MiddleRight; } var cellDebugInfo = parentProp == null ? string.Format("topCell:[{0}].{1}", rowIdx, propName) : string.Format("cell:{0}.{1}[{2}].{3}", parentProp.DeclaringType, parentProp.Name, rowIdx, propName); var cell = new DtoCellViewModel(dependencies, dataCtx, result, fileOpener, tmpService, row, allColumns[prop], new GuiGridLocationAttribute(rowIdx, columnIdx), viewModel, cellDebugInfo); result.Cells.Add(cell); } rowIdx += 1; } return(result); }