/// <summary> /// Event occurs for each image before it is processed /// </summary> /// <param name="sender">sender</param> /// <param name="e">image error event details</param> private void reportDocument_ImageError(object sender, ImageErrorEventArgs e) { e.Handled = true; // just suppress exceptions }
/// <summary> /// Creates a flow document of the report data /// </summary> /// <returns></returns> /// <exception cref="ArgumentException">Flow document must have a specified page height</exception> /// <exception cref="ArgumentException">Flow document must have a specified page width</exception> /// <exception cref="ArgumentException">"Flow document must have only one ReportProperties section, but it has {0}"</exception> public FlowDocument CreateFlowDocument() { MemoryStream mem = new MemoryStream(); byte[] buf = Encoding.UTF8.GetBytes(_xamlData); mem.Write(buf, 0, buf.Length); mem.Position = 0; FlowDocument res = XamlReader.Load(mem) as FlowDocument; if (res.PageHeight == double.NaN) { throw new ArgumentException("Flow document must have a specified page height"); } if (res.PageWidth == double.NaN) { throw new ArgumentException("Flow document must have a specified page width"); } // remember original values _pageHeight = res.PageHeight; _pageWidth = res.PageWidth; // search report properties DocumentWalker walker = new DocumentWalker(); List <SectionReportHeader> headers = walker.Walk <SectionReportHeader>(res); List <SectionReportFooter> footers = walker.Walk <SectionReportFooter>(res); List <ReportProperties> properties = walker.Walk <ReportProperties>(res); if (properties.Count > 0) { if (properties.Count > 1) { throw new ArgumentException(String.Format("Flow document must have only one ReportProperties section, but it has {0}", properties.Count)); } ReportProperties prop = properties[0]; if (prop.ReportName != null) { ReportName = prop.ReportName; } if (prop.ReportTitle != null) { ReportTitle = prop.ReportTitle; } if (headers.Count > 0) { PageHeaderHeight = headers[0].PageHeaderHeight; } if (footers.Count > 0) { PageFooterHeight = footers[0].PageFooterHeight; } // remove properties section from FlowDocument DependencyObject parent = prop.Parent; if (parent is FlowDocument) { ((FlowDocument)parent).Blocks.Remove(prop); parent = null; } if (parent is Section) { ((Section)parent).Blocks.Remove(prop); parent = null; } } // make height smaller to have enough space for page header and page footer res.PageHeight = _pageHeight - _pageHeight * (PageHeaderHeight + PageFooterHeight) / 100d; // search image objects List <Image> images = new List <Image>(); walker.Tag = images; walker.VisualVisited += new DocumentVisitedEventHandler(walker_VisualVisited); walker.Walk(res); // load all images foreach (Image image in images) { if (ImageProcessing != null) { ImageProcessing(this, new ImageEventArgs(this, image)); } try { if (image.Tag is string) { image.Source = new BitmapImage(new Uri("file:///" + Path.Combine(_xamlImagePath, image.Tag.ToString()))); } } catch (Exception ex) { // fire event on exception and check for Handled = true after each invoke if (ImageError != null) { bool handled = false; lock (ImageError) { ImageErrorEventArgs eventArgs = new ImageErrorEventArgs(ex, this, image); foreach (var ed in ImageError.GetInvocationList()) { ed.DynamicInvoke(this, eventArgs); if (eventArgs.Handled) { handled = true; break; } } } if (!handled) { throw; } } else { throw; } } if (ImageProcessed != null) { ImageProcessed(this, new ImageEventArgs(this, image)); } // TODO: find a better way to specify file names } return(res); }
void reportDocument_ImageError(object sender, ImageErrorEventArgs e) { e.Handled = true; }
/// <summary> /// Creates a flow document of the report data /// </summary> /// <returns></returns> /// <exception cref="ArgumentException">Flow document must have a specified page height</exception> /// <exception cref="ArgumentException">Flow document must have a specified page width</exception> /// <exception cref="ArgumentException">"Flow document must have only one ReportProperties section, but it has {0}"</exception> public FlowDocument CreateFlowDocument(out Hint hints) { using (var counter = new TimeCounter("\t\t\tReportDocument Total {0}")) { FlowDocument res = GetFlowDocument(); counter.ShowTick("\t\t\t\tReportDocument Load XAML: {0}"); if (res.PageHeight == double.NaN) throw new ArgumentException("Flow document must have a specified page height"); if (res.PageWidth == double.NaN) throw new ArgumentException("Flow document must have a specified page width"); // remember original values _pageHeight = res.PageHeight; _pageWidth = res.PageWidth; // search report properties DocumentWalker walker = new DocumentWalker(); List<SectionReportHeader> headers = walker.Walk<SectionReportHeader>(res); List<SectionReportFooter> footers = walker.Walk<SectionReportFooter>(res); var hintList = walker.Walk<ReportHint>(res); hints = Hint.None; foreach (var hint in hintList) { hints |= hint.Hint; // remove properties section from FlowDocument DependencyObject parent = hint.Parent; if (parent is FlowDocument) { ((FlowDocument)parent).Blocks.Remove(hint); parent = null; } if (parent is Section) { ((Section)parent).Blocks.Remove(hint); parent = null; } } List<ReportProperties> properties = walker.Walk<ReportProperties>(res); if (properties.Count > 0) { if (properties.Count > 1) throw new ArgumentException(String.Format("Flow document must have only one ReportProperties section, but it has {0}", properties.Count)); ReportProperties prop = properties[0]; if (prop.ReportName != null) ReportName = prop.ReportName; if (prop.ReportTitle != null) ReportTitle = prop.ReportTitle; if (headers.Count > 0) PageHeaderHeight = headers[0].PageHeaderHeight; if (footers.Count > 0) PageFooterHeight = footers[0].PageFooterHeight; // remove properties section from FlowDocument DependencyObject parent = prop.Parent; if (parent is FlowDocument) { ((FlowDocument)parent).Blocks.Remove(prop); parent = null; } if (parent is Section) { ((Section)parent).Blocks.Remove(prop); parent = null; } } // make height smaller to have enough space for page header and page footer res.PageHeight = _pageHeight - _pageHeight * (PageHeaderHeight + PageFooterHeight) / 100d; // search image objects List<Image> images = new List<Image>(); walker.Tag = images; walker.VisualVisited += new DocumentVisitedEventHandler(walker_VisualVisited); walker.Walk(res); // load all images foreach (Image image in images) { if (ImageProcessing != null) ImageProcessing(this, new ImageEventArgs(this, image)); try { if (image.Tag is string) image.Source = new BitmapImage(new Uri("file:///" + Path.Combine(_xamlImagePath, image.Tag.ToString()))); } catch (Exception ex) { // fire event on exception and check for Handled = true after each invoke if (ImageError != null) { bool handled = false; lock (ImageError) { ImageErrorEventArgs eventArgs = new ImageErrorEventArgs(ex, this, image); foreach (var ed in ImageError.GetInvocationList()) { ed.DynamicInvoke(this, eventArgs); if (eventArgs.Handled) { handled = true; break; } } } if (!handled) throw; } else throw; } if (ImageProcessed != null) ImageProcessed(this, new ImageEventArgs(this, image)); // TODO: find a better way to specify file names } return res; } }
/// <summary> /// Creates a flow document of the report data /// </summary> /// <returns></returns> /// <exception cref="ArgumentException">XAML data does not represent a FlowDocument</exception> /// <exception cref="ArgumentException">Flow document must have a specified page height</exception> /// <exception cref="ArgumentException">Flow document must have a specified page width</exception> /// <exception cref="ArgumentException">"Flow document must have only one ReportProperties section, but it has {0}"</exception> public FlowDocument CreateFlowDocument() { MemoryStream mem = new MemoryStream(); byte[] buf = Encoding.UTF8.GetBytes(_xamlData); mem.Write(buf, 0, buf.Length); mem.Position = 0; FlowDocument res = XamlReader.Load(mem) as FlowDocument; if (res == null) throw new ArgumentException("XAML data does not represent a FlowDocument"); if (res.PageHeight == double.NaN) throw new ArgumentException("Flow document must have a specified page height"); if (res.PageWidth == double.NaN) throw new ArgumentException("Flow document must have a specified page width"); // remember original values _pageHeight = res.PageHeight; _pageWidth = res.PageWidth; // search report properties DocumentWalker walker = new DocumentWalker(); List<SectionReportHeader> headers = walker.Walk<SectionReportHeader>(res); List<SectionReportFooter> footers = walker.Walk<SectionReportFooter>(res); List<ReportProperties> properties = walker.Walk<ReportProperties>(res); if (properties.Count > 0) { if (properties.Count > 1) throw new ArgumentException(String.Format("Flow document must have only one ReportProperties section, but it has {0}", properties.Count)); ReportProperties prop = properties[0]; if (prop.ReportName != null) ReportName = prop.ReportName; if (prop.ReportTitle != null) ReportTitle = prop.ReportTitle; if (headers.Count > 0) PageHeaderHeight = headers[0].PageHeaderHeight; if (footers.Count > 0) PageFooterHeight = footers[0].PageFooterHeight; // remove properties section from FlowDocument DependencyObject parent = prop.Parent; if (parent is FlowDocument) { ((FlowDocument)parent).Blocks.Remove(prop); parent = null; } if (parent is Section) { ((Section)parent).Blocks.Remove(prop); } } // make height smaller to have enough space for page header and page footer res.PageHeight = _pageHeight - _pageHeight * (PageHeaderHeight + PageFooterHeight) / 100d; // search image objects List<Image> images = new List<Image>(); walker.Tag = images; walker.VisualVisited += WalkerVisualVisited; walker.Walk(res); // load all images foreach (Image image in images) { if (ImageProcessing != null) ImageProcessing(this, new ImageEventArgs(this, image)); try { if (image.Tag is string) image.Source = new BitmapImage(new Uri("file:///" + Path.Combine(_xamlImagePath, image.Tag.ToString()))); } catch (Exception ex) { // fire event on exception and check for Handled = true after each invoke if (ImageError != null) { bool handled = false; lock (ImageError) { ImageErrorEventArgs eventArgs = new ImageErrorEventArgs(ex, this, image); foreach (var ed in ImageError.GetInvocationList()) { ed.DynamicInvoke(this, eventArgs); if (eventArgs.Handled) { handled = true; break; } } } if (!handled) throw; } else throw; } if (ImageProcessed != null) ImageProcessed(this, new ImageEventArgs(this, image)); // TODO: find a better way to specify file names } return res; }