///<summary>Prints some rows of the details section at the specified x and y position on the page. The math to decide how many rows to print is done ahead of time. The number of rows printed so far is kept global so that it can be used in calculating the layout of this section.</summary> private void PrintDetailsSection(Graphics g, Section section, int xPos, int yPos, int rowsToPrint) { ReportObject textObject; ReportObject fieldObject; //LineObject lineObject; //BoxObject boxObject; StringFormat strFormat; //used each time text is drawn to handle alignment issues string rawText = ""; //the raw text for a given field as taken from the database string displayText = ""; //The formatted text to print string prevDisplayText = ""; //The formatted text of the previous row. Used to test suppress dupl. //loop through each row in the table for (int i = rowsPrinted; i < rowsPrinted + rowsToPrint; i++) { foreach (ReportObject reportObject in MyReport.ReportObjects) { //todo later: check for lines and boxes that span multiple sections. if (reportObject.SectionName != section.Name) { //skip any reportObjects that are not in this section continue; } if (reportObject.ObjectKind == ReportObjectKind.TextObject) { //not typical to print textobject in details section, but allowed textObject = reportObject; strFormat = ReportObject.GetStringFormat(textObject.TextAlign); RectangleF layoutRect = new RectangleF(xPos + textObject.Location.X , yPos + textObject.Location.Y , textObject.Size.Width, textObject.Size.Height); g.DrawString(textObject.StaticText, textObject.Font , new SolidBrush(textObject.ForeColor), layoutRect, strFormat); } else if (reportObject.ObjectKind == ReportObjectKind.FieldObject) { fieldObject = reportObject; strFormat = ReportObject.GetStringFormat(fieldObject.TextAlign); RectangleF layoutRect = new RectangleF(xPos + fieldObject.Location.X, yPos + fieldObject.Location.Y, fieldObject.Size.Width, fieldObject.Size.Height); if (fieldObject.FieldKind == FieldDefKind.DataTableField) { rawText = MyReport.ReportTable.Rows [i][MyReport.DataFields.IndexOf(fieldObject.DataField)].ToString(); displayText = rawText; if (fieldObject.ValueType == FieldValueType.Age) { displayText = Shared.AgeToString(Shared.DateToAge(PIn.PDate(MyReport.ReportTable.Rows[i][MyReport.DataFields.IndexOf(fieldObject.DataField)].ToString()))); //(fieldObject.FormatString); } else if (fieldObject.ValueType == FieldValueType.Boolean) { displayText = PIn.PBool(MyReport.ReportTable.Rows[i][MyReport.DataFields.IndexOf(fieldObject.DataField)].ToString()).ToString(); //(fieldObject.FormatString); if (i > 0 && fieldObject.SuppressIfDuplicate) { prevDisplayText = PIn.PBool(MyReport.ReportTable.Rows[i - 1][MyReport.DataFields.IndexOf(fieldObject.DataField)].ToString()).ToString(); } } else if (fieldObject.ValueType == FieldValueType.Date) { displayText = PIn.PDateT(MyReport.ReportTable.Rows[i][MyReport.DataFields.IndexOf(fieldObject.DataField)].ToString()).ToString(fieldObject.FormatString); if (i > 0 && fieldObject.SuppressIfDuplicate) { prevDisplayText = PIn.PDateT(MyReport.ReportTable.Rows[i - 1][MyReport.DataFields.IndexOf(fieldObject.DataField)].ToString()).ToString(fieldObject.FormatString); } } else if (fieldObject.ValueType == FieldValueType.Integer) { displayText = PIn.PInt(MyReport.ReportTable.Rows[i][MyReport.DataFields.IndexOf(fieldObject.DataField)].ToString()).ToString(fieldObject.FormatString); if (i > 0 && fieldObject.SuppressIfDuplicate) { prevDisplayText = PIn.PInt(MyReport.ReportTable.Rows[i - 1][MyReport.DataFields.IndexOf(fieldObject.DataField)].ToString()).ToString(fieldObject.FormatString); } } else if (fieldObject.ValueType == FieldValueType.Number) { displayText = PIn.PDouble(MyReport.ReportTable.Rows[i][MyReport.DataFields.IndexOf(fieldObject.DataField)].ToString()).ToString(fieldObject.FormatString); if (i > 0 && fieldObject.SuppressIfDuplicate) { prevDisplayText = PIn.PDouble(MyReport.ReportTable.Rows[i - 1][MyReport.DataFields.IndexOf(fieldObject.DataField)].ToString()).ToString(fieldObject.FormatString); } } else if (fieldObject.ValueType == FieldValueType.String) { displayText = rawText; if (i > 0 && fieldObject.SuppressIfDuplicate) { prevDisplayText = MyReport.ReportTable.Rows[i - 1][MyReport.DataFields.IndexOf(fieldObject.DataField)].ToString(); } } //suppress if duplicate: if (i > 0 && fieldObject.SuppressIfDuplicate && displayText == prevDisplayText) { displayText = ""; } } else if (fieldObject.FieldKind == FieldDefKind.FormulaField) { //can't do formulas yet } else if (fieldObject.FieldKind == FieldDefKind.SpecialField) { } else if (fieldObject.FieldKind == FieldDefKind.SummaryField) { } g.DrawString(displayText, fieldObject.Font , new SolidBrush(fieldObject.ForeColor), layoutRect, strFormat); } //incomplete: else if lines //incomplete: else if boxes. } //foreach reportObject yPos += section.Height; } //for i rows rowsPrinted += rowsToPrint; }
/// <summary> /// Creates an object of type <typeparamref name="T"/> based on a <see cref="DataRow"/>. /// The fields of the <see cref="DataRow"/> can be either of the corresponding type, or of the /// <see cref="String"/> type. In the case of a <see cref="String"/>, conversion will be done using /// the <see cref="PIn"/> data class. /// </summary> /// <param name="row"> /// A <see cref="DataRow"/> containing rows corresponding to objects of type <typeparamref name="T"/>. /// </param> /// <returns> /// An objects of type <typeparamref name="T"/>. /// </returns> /// <remarks> /// <para> /// This method is for compatibility purposes only. /// </para> /// <para> /// This method needs to be tested. /// </para> /// </remarks> public static T CreateObject(DataRow row) { if (row == null) { throw new ArgumentNullException("row"); } Collection <T> values = new Collection <T>(); Collection <DataFieldInfo> dataFields = DataObjectInfo <T> .GetDataFields(); T value = new T(); foreach (DataFieldInfo dataField in dataFields) { if (dataField.WriteOnly) { continue; } // Retrieve the value and its type, both in the database and code. object dataValue = row[dataField.DatabaseName]; Type dataType = row.Table.Columns[dataField.DatabaseName].DataType; Type codeType = dataField.Field.FieldType; if (codeType != typeof(string) && dataType == typeof(string)) { // If the type in the dataset is "string", but the type in the code // object isn't "string", we use the PIn class. if (dataType == typeof(Bitmap)) { dataValue = PIn.PBitmap((string)dataValue); } else if (dataType == typeof(bool)) { dataValue = PIn.PBool((string)dataValue); } else if (dataType == typeof(Byte)) { dataValue = PIn.PByte((string)dataValue); } else if (dataType == typeof(DateTime)) { // NOTE: Is there any difference between PIn.PDate and PIn.PDateT? dataValue = PIn.PDate((string)dataValue); } else if (dataType == typeof(double)) { dataValue = PIn.PDouble((string)dataValue); } else if (dataType == typeof(float)) { dataValue = PIn.PFloat((string)dataValue); } else if (dataType == typeof(int)) { dataValue = PIn.PInt((string)dataValue); } else { // NOTE: Support for "Sound" is not here yet. Maybe it should be exported // to a byte[] type and then saved, don't know. throw new NotSupportedException(Resources.DataTypeNotSupportedByPIn); } } else { // The object is stored in it's "true" type in the DataSet as well (no conversions to // string types have been done). We can, normally, directly use it, except for a couple // of special cases. if (codeType == typeof(bool)) { // Booleans are sometimes stored as TINYINT(3), to enable conversion to // Enums if required. Hence, we need to do an explicit conversion. dataField.Field.SetValue(value, Convert.ToBoolean(dataValue)); } else if (codeType == typeof(DateTime)) { // DateTime fields can have various minimum or default values depending on // the database type. In MySql, for example, it is 00-00-00, which is not supported // by .NET. So for now, we catch a cast exception and set it to DateTime.MinValue. try { dataField.Field.SetValue(value, DateTime.Parse(dataValue.ToString())); } catch { dataField.Field.SetValue(value, DateTime.MinValue); } } else { dataField.Field.SetValue(value, dataValue); } } } return(value); }