1

The Application

I am working on an EHR application. The page I am working on converts the contents of a XAML file's data to an XPS file which can be printed or drawn on. When the page's data in on the XAML page it can easily be scrolled through and the data is kept inside a BlockUIContainer. However once the XPS file is generated, some sections are cut off.

Application Code

Inside the 10-14YearVisit form XAML file

<!--History Section-->
      <BlockUIContainer>
        <genForms_Controls:PatientHistoryUC />
      </BlockUIContainer>
<!--History Bottom-->

The PatientHistoryUC.xaml (Sorry, lots of code!)

<UserControl x:Class="Pcis.Emr.GeneralForms.Controls.PatientHistoryUC"
             xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
             xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
             xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
             xmlns:genForms_Controls="clr-namespace:Pcis.Emr.GeneralForms.Controls"
             xmlns:galenControls="clr-namespace:Pcis.Emr.GeneralForms.Galen.Controls"
             xmlns:util="clr-namespace:Pcis.Emr.Common.Utils;assembly=Pcis.Emr.Common"
             xmlns:sectionDatas="clr-namespace:Pcis.Emr.Data.SectionDatas;assembly=Pcis.Emr.Data"
             xmlns:d="http://schemas.microsoft.com/expression/blend/2008">
  <Border BorderBrush="Black"
          BorderThickness="1"
          CornerRadius="5"
          Width="790"
          Margin="0,0,2,5">
    <Grid>
      <Grid.ColumnDefinitions>
        <ColumnDefinition Width="*" />
        <ColumnDefinition Width="*" />
      </Grid.ColumnDefinitions>
      <Grid.RowDefinitions>
        <RowDefinition Height="Auto" />
        <RowDefinition Height="Auto" />
        <RowDefinition Height="Auto" />
        <RowDefinition Height="Auto" />
      </Grid.RowDefinitions>
      <!--past medical history-->
      <galenControls:GalenPastMedicalHistory Grid.ColumnSpan="2"
                                             util:FormTemplateSectionUtil.ShowInForm="{x:Static sectionDatas:SectionType.ProblemList}"
                                             util:FormTemplateSectionUtil.TemplateId="{Binding TemplateId}"
                                             Margin="3"/>
      <genForms_Controls:ProblemsSection PMHFontSize="11"
                                         Margin="3"
                                         Grid.Row="1"
                                         Grid.ColumnSpan="2"
                                         util:FormTemplateSectionUtil.ShowInForm="{x:Static sectionDatas:SectionType.Problems}"
                                         util:FormTemplateSectionUtil.TemplateId="{Binding TemplateId}" />
      <StackPanel Grid.Row="2"
                  Margin="3">
        <!--past surgical history-->
        <Button Grid.Column="0"
                VerticalAlignment="Top"
                Style="{StaticResource NoBorderButtonHand}"
                Command="{Binding PickPSHCommand, Mode=OneWay}"
                HorizontalAlignment="Left">
          <TextBlock VerticalAlignment="Center"
                     FontWeight="Bold"
                     Text="Past Surgical History"
                     TextDecorations="Underline"
                     HorizontalAlignment="Left"
                     Foreground="Blue" />
        </Button>
        <ItemsControl Grid.Column="0"
                      Margin="0,0,6,0"
                      ItemTemplate="{DynamicResource PSHItemTemplate}"
                      ItemsSource="{Binding PastSurgicalHistoryChronicOnly, Mode=Default}"
                      VerticalAlignment="Top" />
      </StackPanel>
      <StackPanel x:Name="FH_SH"
                  Grid.Column="4"
                  Grid.Row="2"
                  Margin="3"
                  HorizontalAlignment="Left"
                  VerticalAlignment="Top">
        <!--Family history-->
        <galenControls:GalenFamilyHistory />

        <genForms_Controls:SocialHistoryUCTreeView />
        <Grid>
          <Grid.ColumnDefinitions>
            <ColumnDefinition Width="Auto" />
            <ColumnDefinition />
          </Grid.ColumnDefinitions>
        </Grid>
      </StackPanel>
      <StackPanel x:Name="PMH_PSH"
                  Grid.Column="0"
                  Grid.Row="2"
                  Grid.ColumnSpan="2"
                  HorizontalAlignment="Left"
                  Width="390.423"
                  Margin="3">
        <Grid Margin="0,5,0,0"
              Grid.Row="1">
          <Grid.ColumnDefinitions>
            <ColumnDefinition Width="0.799*" />
            <ColumnDefinition Width="0.201*" />
          </Grid.ColumnDefinitions>
          <!--current medications-->
          <StackPanel Grid.Column="1"
                      Orientation="Horizontal"                      
                      Margin="0,0,8,0"
                      HorizontalAlignment="Right"
                      Width="249" />
        </Grid>
      </StackPanel>
    </Grid>
  </Border>
</UserControl>

xps file generation

    public bool SaveDocument(
    out string path,
    out string error,
    bool digitallySign = true,
    SerializerWriterCollator customCollator = null,
    PageRange? pr = null,
    string headerText = null,
    bool printAccount = true,
    HorizontalAlignment patientAlignment = HorizontalAlignment.Center,
    HorizontalAlignment headerTextAlignment = HorizontalAlignment.Center,
    HorizontalAlignment logoAlignment = HorizontalAlignment.Right,
    int headerFontSize = 13,
    Typeface headerTypeFace = null,
    string generatedNote = null,
    bool alwaysThrow = false)
    {
      path = Util.GetTempFile("xps");
      error = string.Empty;

      SerializerWriterCollator collator;
      XpsDocument doc = null;
      bool endBatchWrite = false;

      if (customCollator != null)
      {
        collator = customCollator;
      }
      else
      {
        doc = new XpsDocument(path, FileAccess.ReadWrite);
        XpsDocumentWriter writer = XpsDocument.CreateXpsDocumentWriter(doc);
        collator = writer.CreateVisualsCollator();
        collator.BeginBatchWrite();
      }

      int count = 1;
      int flowDocumentCount = 0;

      foreach (FlowDocument flowdoc in this.Documents)
      {
        if (pr != null && pr.Value.PageTo != 0 && (count < pr.Value.PageFrom || count > pr.Value.PageTo))
        {
          continue;
        }

        IDocumentPaginatorSource source = flowdoc;
        DocumentPaginator p = source.DocumentPaginator;

        p.PageSize = new Size(this.extentWidth, this.extentHeight);
        p.ComputePageCount();
        this.TotalPages += p.PageCount;

        flowDocumentCount += p.PageCount;
      }

      int currentPage = 1;

      foreach (FlowDocument flowdoc in this.Documents)
      {
        IDocumentPaginatorSource source = flowdoc;
        DocumentPaginator p = source.DocumentPaginator;

        p.PageSize = new Size(this.extentWidth, this.extentHeight);
        p.ComputePageCount();

        for (int i = 0; i < p.PageCount; ++i)
        {
          DocumentPage page = p.GetPage(i);
          ContainerVisual v = new ContainerVisual();
          DrawingVisual header = this.CreateHeader(
            currentPage++,
            this.TotalPages,
            digitallySign,
            headerText,
            printAccount,
            patientAlignment,
            headerTextAlignment,
            logoAlignment,
            headerFontSize,
            headerTypeFace);

          ContainerVisual cv = new ContainerVisual();
          cv.Children.Add(page.Visual);

          // This offset is how far down the header will show.  If the logo cuts off, it's because
          // it extends below the Y variable in the line of code below in the new Vector(x,y)
          cv.Offset = new Vector(0, 45);
          v.Children.Add(cv);

          v.Children.Add(header);

          v.Transform = new ScaleTransform(0.96, 1);
          v.Offset = new Vector(24, 0);
          collator.Write(v);
          endBatchWrite = true;

          Util.LogAccess("Printing a Document", AccessLogComponent.HealthRecord, AccessLogAction.Print);
        }
      }

      if (customCollator == null)
      {
        if (endBatchWrite == true)
        {
          collator.EndBatchWrite();
        }

        doc.Close();
      }

      // Minus on from the current page due to the fact that we start on page 1.
      return this.HandleCreationError(currentPage - 1, flowDocumentCount, path, generatedNote, alwaysThrow, out error);
    }

Example of Before and After: (All of the patient data is made up)

Pre-XPS PreXPS

XPS

XAML file

PatientHistoryUC.xaml Layout Layout

What I want to happen

Depending on the amount of data being supplied to the XPS generated file, pagination occurs which moves excess contents to the next page rather than cutting off. I believe the BlockUIContainer is the main issue as it can't be split into two when the data becomes too much for the set page size (8 x 11).

Thank you for reading.

Abhi Tiwari
  • 137
  • 1
  • 6

0 Answers0