0

I'm trying to write a function that will write the results of a test (which have both text output and chart output, stored in a textbox and a livecharts chart respectively) to a pdf file. There are no issues with the text output, but I haven't been able to get the charts to save unless I extract each chart from its parent stackpanel (each test has a stackpanel that is shown when the test is selected) and then display the chart in a separate window. There is a lot of code around the problematic lines, so I'm going to paste a shortened version below.

The issue seems to be calling "_saveWindow.Show()" instead of ".ShowDialog". I need this to open and close without user input, but the "Show()" doesn't draw the chart in the window at all.

Any ideas why this is happening?

foreach (TestSequenceItem tsi in resultsToSave)
{
     tsi.Instances[0].ChartStackPanel.Visibility = Visibility.Visible;

     for (int i=0; i<tsi.Instances[0].StackChartList.Count; i++)
     {
          Chart _saveChart = tsi.Instances[0].StackChartList[i];
          tsi.Instances[0].ChartStackPanel.Children.Remove(_saveChart);

          ScrollViewer panel = new ScrollViewer { Content = _saveChart };
          Window _saveWindow = new Window { Content = panel };

          _saveWindow.Show();

          var encoder = new PngBitmapEncoder();
          RenderTargetBitmap bmp = new RenderTargetBitmap((int)tsiChartDoc.DefaultPageSetup.PageWidth, 600, 96, 96, PixelFormats.Pbgra32);
          bmp.Render(_saveChart);
          encoder.Frames.Add(BitmapFrame.Create(bmp));

          using (MemoryStream stm = new MemoryStream())
          {
               encoder.Save(stm);

               string fileName = "base64:" + Convert.ToBase64String(stm.ToArray());

               // Adding a heading to the pdf
               tsiChartDoc.LastSection.AddParagraph(tsi.Instances[0].StackTitleList[i].Text, "Heading2");

               tsiChartDoc.LastSection.AddImage(fileName);
          }

          _saveWindow.Close();
          panel.Content = null;
                            
          tsi.Instances[0].ChartStackPanel.Children.Insert(chartIdx, _saveChart);
     }
}
John Snow
  • 9
  • 1
  • It's unclear why you have the Window at all. You would usually take a UI element like the Chart, call its Measure and Arrange (and perhaps InvalidateVisual) methods and then pass it to RenderTargetBitmap.Render. If the element has some Margin you could also use an intermediate DrawingVisual. See for example [this](https://stackoverflow.com/a/42996826/1136211) and [this](https://stackoverflow.com/a/55546728/1136211). – Clemens Jul 14 '21 at 06:42
  • I'm not sure why the window is necessary, but even calling invalidate visual doesn't actually show the chart. The only charts that save are the ones visible on the screen at the time (without the window). So, if there are 2 sets of charts, the only ones that save are set 1 chart 1 and like... the top 10% of set 1 chart 2 – John Snow Jul 14 '21 at 18:43

0 Answers0