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
XPS
PatientHistoryUC.xaml 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.