I'm trying to print a Window containing a single TextBox. When displayed on screen the red validation error border is correctly present. When printed via PrintDialog, the border is missing. The window is defined as:
public partial class ReportPage : INotifyDataErrorInfo
{
public ReportPage()
{
DataContext = this;
SomeText = "hi there";
InitializeComponent();
}
public string SomeText { get; set; }
public IEnumerable GetErrors(string propertyName)
{
return propertyName == "SomeText" ? new [] {"some error"} : null;
}
public bool HasErrors => true;
public event EventHandler<DataErrorsChangedEventArgs> ErrorsChanged;
}
Note how it serves as the Window, view model, and error implementation. It specifies that the lone property, SomeText, is in error. The corresponding XAML is as follows:
<Window x:Class="ReportPage"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
mc:Ignorable="d">
<Grid x:Name="MainContent" VerticalAlignment="Center" HorizontalAlignment="Center">
<TextBox x:Name="MyText" Text="{Binding SomeText}"/>
</Grid>
</Window>
To print the contents of the Window I use:
var printDialog = new PrintDialog { PrintTicket = { PageOrientation = PageOrientation.Portrait } };
printDialog.ShowDialog();
var caps = printDialog.PrintQueue.GetPrintCapabilities(printDialog.PrintTicket);
var rect = new Rect(new Point(caps.PageImageableArea.OriginWidth, caps.PageImageableArea.OriginHeight),
new Size(caps.PageImageableArea.ExtentWidth, caps.PageImageableArea.ExtentHeight));
var pageSize = rect.Size;
var origin = rect.TopLeft;
var fullSize = new Size(printDialog.PrintTicket.PageMediaSize.Width.Value,
printDialog.PrintTicket.PageMediaSize.Height.Value);
var page = new ReportPage
{
Margin = new Thickness(
Math.Max(72 - origin.X, 0),
Math.Max(48 - origin.Y, 0),
Math.Max(72 - (fullSize.Width - pageSize.Width - origin.X), 0),
Math.Max(96 - (fullSize.Height - pageSize.Height - origin.Y), 0))
};
page.MainContent.Measure(pageSize);
page.MainContent.Arrange(new Rect(origin, pageSize));
page.MainContent.UpdateLayout();
printDialog.PrintVisual(page.MainContent, "some description");
I see the TextBox just fine, but no red border. I've tried adding an <AdornerDecorator> around the MainContent Grid to no avail. What happens when showing a Window on-screen to cause the red border to be visible that doesn't happen when printing?
First, adornments aren't rendered without showing the
Window. To fix this theWindow, prior to printing, is shown off-screen (Left/Topare arbitrarily set to -10000 andShowInTaskbar/ShowActivatedare set tofalse):Second, there's no adornment layer when printing just MainContent, so one must added (see XPS Printing of an Adorner: