microsoft / microsoft/microsoft-ui-xaml

Print Preview does not show image elements

Open
#11,095 1 comment 1 reaction 0 assignees View on GitHub
bug needs-triage
Dominant language
C++
Stars
8.4k
Forks
942
Avg merge
2d 7h
Merged PRs (30d)
105

Description

### Describe the bug

(originally from a discussion [on StackOverflow](https://stackoverflow.com/questions/79939304/print-preview-doesnt-show-all-elements), I was advised this is a bug)

I want to print from a WinUI 3 app but am having a problem where images don't always show up. I am following the document [Print from your app](https://learn.microsoft.com/en-us/windows/apps/develop/devices-sensors/print-from-your-app) and the [Coloring Book](https://github.com/microsoft/Windows-appsample-coloringbook) sample.

I am finding that images do not show up on the first page (or sometimes two pages) of the preview, and are also missing from the printout (just using print-to-pdf). The images are just loaded from local URLs in the Assets folder. I suspect something to do with async, i.e. the image pixels aren't ready at the time the preview is assembled, because the preview does usually work if I cancel and start again.

This is with .NET10, WinUI 3 2.0

### Why is this important?

Print preview does not work properly - a user will be confused by blank areas where images should be.

### Steps to reproduce the bug

The full code is on [GitHub](https://github.com/pedro-w/PrintDemo)

# Main window

Registering for print

https://github.com/pedro-w/PrintDemo/blob/474c9e919797f2503bc4ca0c1d82edf35572e938/MainWindow.xaml.cs#L46-L63

```c#
private void PrintRegistration(bool reg)
{
var hWnd = WinRT.Interop.WindowNative.GetWindowHandle(this);
if (hWnd == IntPtr.Zero) { return; }
PrintManager printManager = PrintManagerInterop.GetForWindow(hWnd);
if (reg)
{
// Register actions
printManager.PrintTaskRequested += PrintManager_PrintTaskRequested;
layout = new PrintLayout();
}
else
{
// Unregister actions
printManager.PrintTaskRequested -= PrintManager_PrintTaskRequested;
layout = null;
}
}
```

Print button handler

https://github.com/pedro-w/PrintDemo/blob/474c9e919797f2503bc4ca0c1d82edf35572e938/MainWindow.xaml.cs#L20-L45

```c#
private void PrintManager_PrintTaskRequested(PrintManager sender, PrintTaskRequestedEventArgs args)
{
if (layout != null)
{
IPrintDocumentSource documentSource = layout.DocumentSource;
args.Request.CreatePrintTask("Printing Demo", (task) => { task.SetSource(documentSource); });
}
}
```

# Print layout

https://github.com/pedro-w/PrintDemo/blob/474c9e919797f2503bc4ca0c1d82edf35572e938/PrintLayout.cs

```c#
internal class PrintLayout
{
internal PrintLayout()
{
printDocument = new PrintDocument();
printDocument.AddPages += AddPages;
printDocument.GetPreviewPage += GetPreviewPage;
printDocument.Paginate += Paginate;
documentSource = printDocument.DocumentSource;
}
private static Canvas MakeCanvas(PrintPageDescription pageDescription, UIElement content)
{
double marginLeftRight = DIP * 1.0;
double marginTopBottom = DIP * 1.0;
// Canvas covers the whole page
Canvas page0 = new() { Width = pageDescription.PageSize.Width, Height = pageDescription.PageSize.Height };
// Resize and position the content to respect the margins and the ImageableRect
double left = Math.Max(marginLeftRight, pageDescription.ImageableRect.Left);
double right = Math.Min(pageDescription.PageSize.Width - marginLeftRight, pageDescription.ImageableRect.Right);
double top = Math.Max(marginTopBottom, pageDescription.ImageableRect.Top);
double bottom = Math.Min(pageDescription.PageSize.Height - marginTopBottom, pageDescription.ImageableRect.Bottom);
page0.Children.Add(content);
// Set the size if we can
if (content is FrameworkElement el)
{
el.Width = right - left;
el.Height = bottom - top;
}
Canvas.SetLeft(content, left);
Canvas.SetTop(content, top);
return page0;

}
private static Canvas MakeFrontPage(PrintPageDescription pageDescription)
{
FrontPage fp = new();
Canvas page = MakeCanvas(pageDescription, fp);
return page;
}
private static Canvas MakeImagePage(int pagen, PrintPageDescription pageDescription)
{

ImagePage ip = new($"Page {pagen}");
Canvas page = MakeCanvas(pageDescription, ip);
return page;
}
private void Paginate(object sender, PaginateEventArgs e)
{
if (sender is PrintDocument document)
{
PrintTaskOptions options = e.PrintTaskOptions;
PrintPageDescription pageDescription = options.GetPageDescription(0);
printPreviewPages.Clear();
// Add a front page
Canvas page1 = MakeFrontPage(pageDescription);
printPreviewPages.Add(page1);
// And four image pages
for (int i = 2; i <= 5; ++i)
{
Canvas pageN = MakeImagePage(i, pageDescription);
printPreviewPages.Add(pageN);
}

document.SetPreviewPageCount(printPreviewPages.Count, PreviewPageCountType.Final);
}
}

private void GetPreviewPage(object sender, GetPreviewPageEventArgs e)
{
if (sender is PrintDocument document)
{
UIElement el = printPreviewPages[e.PageNumber - 1];
document.SetPreviewPage(e.PageNumber, el);
}
}

private void AddPages(object sender, AddPagesEventArgs e)
{
if (sender is PrintDocument document)
{
foreach (UIElement elem in printPreviewPages)
{
document.AddPage(elem);
}
document.AddPagesComplete();
}
}

private const double DIP = 96.0; // conversion factor from Device Independent Pixels to inch.

private readonly PrintDocument printDocument;
private readonly IPrintDocumentSource documentSource;
public IPrintDocumentSource DocumentSource { get => documentSource; }

private readonly List printPreviewPages = [];

}
```

# Image page to be printed

```xml









```

### Actual behavior

What happens is the first page with no images is OK, second page has no images, third and subsequent pages are OK
I'm not seeing any errors in the debug log.

### Expected behavior

Each image preview page should have 6 images in it (see screenshot)

### Screenshots

Image

### NuGet package version

Microsoft.WindowsAppSDK 2.0.1

### Windows version

Windows 11 (24H2): Build 26100

### Additional context

_No response_

Contributor guide

Open the contributing guide

Research direction

Start by reproducing the issue with the linked PrintDemo sample, then read MainWindow.xaml.cs, PrintLayout.cs, and ImagePage.xaml, focusing on the PrintDocument pagination, preview, and page-add callbacks. Confirm the behavior across the first several pages and compare it with the expected result of six visible images on every image page.

Written by the indexing model from the issue text.

Assessment

Tech stack
csharp
Domain
desktop
Issue type
Bug
Difficulty
4/5
Estimated time
3-5 days
Activity status
Quiet
Clarity
Mostly clear
Newbie friendliness
48/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.