问题描述
我想将 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>svg{height:140px; width:140px;} p{font-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);
}
}
解决方法
用 WebView 数据填充矩形
根据您的描述,在调用 print api 之前,您似乎没有在 xaml 中呈现矩形。并将其插入到 Route::get('search',[HomeController::class,'search'])->name('search');
页面中。请参考此案例 reply 并首先渲染矩形。
printDoc
更新
在检查你的代码时,我找到了原因,问题是你没有在可视化树中呈现你的 WebView,使 Rectangle page = (Rectangle)this.FindName("MyWebViewRectangle");
printDoc.AddPage(page);
printDoc.AddPagesComplete();
不起作用。 通常需要在与 WebView 源代码相同的 UI 中为在 XAML 中声明的 WebViewBrush 调用 Redraw。有关更多信息,请参阅 this。
您可以使用以下行来验证这一点。
WebViewBrush