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; }
/// <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); }
/// <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); }