打印以编程方式创建的矩形
Posted
技术标签:
【中文标题】打印以编程方式创建的矩形【英文标题】:Print rectangle created programmatically 【发布时间】:2021-06-15 08:16:19 【问题描述】:我想将 WebView 设置为 WebViewBrush
以便添加内部矩形和打印矩形。我想在后端做所有事情,我不想使用 XAML 代码。
我这样做是因为我在获得打印预览时得到模糊/模糊的文本。所以人们说解决这个问题的方法是创建WebViewBrush
,然后创建一个矩形来打印它
首先我将画布和画笔创建为:
private Windows.UI.Xaml.Controls.WebView ViewToPrint = new Windows.UI.Xaml.Controls.WebView();
private Windows.UI.Xaml.Controls.WebViewBrush wvBrush = new Windows.UI.Xaml.Controls.WebViewBrush();
private Windows.UI.Xaml.Shapes.Rectangle rectangle = new Windows.UI.Xaml.Shapes.Rectangle();
然后在方法中我将 WebView 分配给 WebViewBrush 并将其添加到矩形中,
public async void Print(Xamarin.Forms.WebView viewToPrint, string html)
ViewToPrint.NavigateToString(html);
wvBrush.SetSource(ViewToPrint);
wvBrush.Redraw();
rectangle.Fill = wvBrush;
rectangle.Width = 200;
rectangle.Height = 200;
然后在打印预览方法中,我希望看到矩形预览为:
private void PrintDoc_GetPreviewPage(object sender, GetPreviewPageEventArgs e)
printDoc.SetPreviewPage(e.PageNumber, rectangle);
但是我的矩形是空白的,我看不到里面的任何东西。我做错了什么
重现问题:
Xamarin 共享项目类:
private readonly IPrintUWPService _printUWPService = DependencyService.Get<IPrintUWPService>();
public void Printhtml()
var meta = "<meta name='viewport' content='width=device-width, initial-scale=5.0, maximum-scale=5.0, minimum-scale=1.0'>";
var style = "<style>svgheight:140px; width:140px; pfont-size:20px; </style>";
var _htmlSource = @$"
<!DOCTYPE html>
<html>
<head>
meta
style
</head>
<body>
<table border = '1px solid'; style='border-collapse:collapse;'>
<tbody>
<tr>
<td>qr</td>
<td>
<p><b>Heat Number:number</b></p>
<p><b> Cylinder Type Name: cylindername</b></p>
<p><b> Color: colorname</b></p>
</td>
</tr>
</tbody>
</table>
</body>
</html>
";
Print(_htmlSource);
public void Print(string _htmlSource)
_printUWPService.Print( _htmlSource);
共享项目中的接口:
public interface IPrintUWPService
void Print(string html);
UWP 项目服务:
public class PrintUWPService : IPrintUWPService
PrintManager printmgr = PrintManager.GetForCurrentView();
PrintDocument PrintDoc;
PrintDocument printDoc;
PrintTask Task;
private Windows.UI.Xaml.Controls.WebView ViewToPrint = new Windows.UI.Xaml.Controls.WebView();
private DeviceInformationCollection deviceCollection;
private Windows.UI.Xaml.Shapes.Rectangle rectangle = new Windows.UI.Xaml.Shapes.Rectangle();
public PrintUWPService()
printmgr.PrintTaskRequested += Printmgr_PrintTaskRequested;
public async void Print(Xamarin.Forms.WebView viewToPrint, string html)
ViewToPrint.NavigateToString(html);
//MakePage();
if (PrintDoc != null)
printDoc.GetPreviewPage -= PrintDoc_GetPreviewPage;
printDoc.Paginate -= PrintDoc_Paginate;
printDoc.AddPages -= PrintDoc_AddPages;
printDoc = new PrintDocument();
try
printDoc.GetPreviewPage += PrintDoc_GetPreviewPage;
printDoc.Paginate += PrintDoc_Paginate;
printDoc.AddPages += PrintDoc_AddPages;
var showprint = PrintManager.ShowPrintUIAsync();
catch (Exception e)
Debug.WriteLine(e.ToString());
PrintDoc = null;
GC.Collect();
private void MakePage()
var brush = new WebViewBrush
Stretch = (Windows.UI.Xaml.Media.Stretch)Windows.UI.Xaml.Media.Stretch.Uniform
;
brush.SetSource(ViewToPrint);
brush.Redraw();
using (var waitHandle = new System.Threading.ManualResetEventSlim(initialState: false))
waitHandle.Wait(TimeSpan.FromMilliseconds(5000));
rectangle.Width = 200;
rectangle.Height = 200;
rectangle.Fill = brush;
brush.Stretch = (Windows.UI.Xaml.Media.Stretch)Windows.UI.Xaml.Media.Stretch.UniformToFill;
brush.AlignmentY = AlignmentY.Top;
rectangle.Name = "MyWebViewRectangle";
rectangle.Visibility = Windows.UI.Xaml.Visibility.Visible;
private void Printmgr_PrintTaskRequested(PrintManager sender, PrintTaskRequestedEventArgs args)
var deff = args.Request.GetDeferral();
Task = args.Request.CreatePrintTask($"Card Stock DateTime.Now", OnPrintTaskSourceRequested);
deff.Complete();
async void OnPrintTaskSourceRequested(PrintTaskSourceRequestedArgs args)
var def = args.GetDeferral();
await Windows.ApplicationModel.Core.CoreApplication.MainView.CoreWindow.Dispatcher.RunAsync(Windows.UI.Core.CoreDispatcherPriority.Normal, () =>
args.SetSource(printDoc.DocumentSource);
);
def.Complete();
private void PrintDoc_AddPages(object sender, AddPagesEventArgs e)
printDoc.AddPage(rectangle);
printDoc.AddPagesComplete();
private async void PrintDoc_Paginate(object sender, PaginateEventArgs e)
PrintTaskOptions printingOptions = ((PrintTaskOptions)e.PrintTaskOptions);
deviceCollection = await DeviceInformation.FindAllAsync("System.Devices.InterfaceClassGuid:=\"0ecef634-6ef0-472a-8085-5ad023ecbccd\"");
var rolloPrinter = deviceCollection.Where(x => x.Name.Contains("Rollo")).SingleOrDefault();
// Get the page description to deterimine how big the page is
PrintPageDescription pageDescription = printingOptions.GetPageDescription(0);
PrintTaskOptions opt = Task.Options;
printDoc.SetPreviewPageCount(1, PreviewPageCountType.Final);
private void PrintDoc_GetPreviewPage(object sender, GetPreviewPageEventArgs e)
printDoc.SetPreviewPage(e.PageNumber, rectangle);
【问题讨论】:
【参考方案1】:用 WebView 数据填充矩形
根据您的描述,在调用 print api 之前,您似乎没有在 xaml 中渲染矩形。并将其插入printDoc
页面。请参考这个案例reply,先渲染矩形。
Rectangle page = (Rectangle)this.FindName("MyWebViewRectangle");
printDoc.AddPage(page);
printDoc.AddPagesComplete();
更新
在检查你的代码时,我找到了原因,问题是你没有在视觉树中渲染你的 WebView 使得 WebViewBrush
不起作用。 通常需要为在 XAML 中声明的 WebViewBrush 在与 WebView 源相同的 UI 中调用 Redraw。 有关更多信息,请参阅 this。
您可以使用以下行来验证这一点。
public void Print(string html)
// render current ViewToPrint
Window.Current.Content = ViewToPrint;
ViewToPrint.NavigateToString(html);
if (PrintDoc != null)
printDoc.GetPreviewPage -= PrintDoc_GetPreviewPage;
printDoc.Paginate -= PrintDoc_Paginate;
printDoc.AddPages -= PrintDoc_AddPages;
printDoc = new PrintDocument();
try
printDoc.GetPreviewPage += PrintDoc_GetPreviewPage;
printDoc.Paginate += PrintDoc_Paginate;
printDoc.AddPages += PrintDoc_AddPages;
var showprint = PrintManager.ShowPrintUIAsync();
catch (Exception e)
Debug.WriteLine(e.ToString());
//PrintDoc = null;
//GC.Collect();
【讨论】:
我没有在服务上使用 XAML。所以我不能使用“this.FindName”,这就是我使用矩形作为全局变量的原因。所以我尝试:Windows.UI.Xaml.Shapes.Rectangle page = (Windows.UI.Xaml.Shapes.Rectangle)rectangle; printDoc.SetPreviewPage(e.PageNumber, page);
但是是一样的。空白页
它是否呈现在您当前的内容中?
如果我直接使用ViewToPrint.NavigateToString(html);
为:printDoc.SetPreviewPage(e.PageNumber, ViewToPrint);
它可以正常工作,我可以正确获得打印视图但存在模糊问题,所以我想将其转换为矩形来解决它
我认为矩形需要在打印之前渲染。
但是在调用服务时会渲染矩形,因为它是全局变量还是我错了?以上是关于打印以编程方式创建的矩形的主要内容,如果未能解决你的问题,请参考以下文章
当内部按钮触摸时,如何从 Superview 中删除以编程方式创建的子视图?
如何获取在 Xamarin MacOS 中以编程方式创建的 NSTextField 的值?