如何在 UWP 后台任务中使用 XAML UI 元素?
How to use XAML UI element in UWP Background task?
问题: 我正在尝试用其他一些 UI 元素(主要是文本块)创建一个网格,然后使用 RenderTargetBitmap
渲染网格和最后将其保存到图像文件中,在 后台任务
方法代码如下:
private async Task<bool> RenderGridAsync()
{
Grid mainGrid = new Grid();
TextBlock tText = new TextBlock()
{
HorizontalAlignment = HorizontalAlignment.Left,
TextWrapping = TextWrapping.Wrap,
Text = "Some Example Text",
VerticalAlignment = VerticalAlignment.Top,
FontSize = 72,
FontWeight = FontWeights.SemiLight
};
mainGrid.Children.add(tText);
RenderTargetBitmap rtb = new RenderTargetBitmap();
await rtb.RenderAsync(mainGrid);
var pixelBuffer = await rtb.GetPixelsAsync();
var pixels = pixelBuffer.ToArray();
var displayInformation = DisplayInformation.GetForCurrentView();
var file = await ApplicationData.Current.LocalFolder.CreateFileAsync("CurrentImage" + ".png", CreationCollisionOption.ReplaceExisting);
using (var stream = await file.OpenAsync(FileAccessMode.ReadWrite))
{
var encoder = await BitmapEncoder.CreateAsync(BitmapEncoder.PngEncoderId, stream);
encoder.SetPixelData(BitmapPixelFormat.Bgra8,
BitmapAlphaMode.Premultiplied,
(uint)rtb.PixelWidth,
(uint)rtb.PixelHeight,
displayInformation.RawDpiX,
displayInformation.RawDpiY,
pixels);
await encoder.FlushAsync();
}
}
但是当我从后台任务的 运行() 方法调用此方法时,出现以下错误:
我用谷歌搜索了一下异常,发现为了从非 UI 线程更新 UI 元素,我需要使用这个:
await Windows.ApplicationModel.Core.CoreApplication.MainView.CoreWindow.Dispatcher
.RunAsync(CoreDispatcherPriority.Normal, async () => {
await RenderGridAsync();
});
但即使这样也给了我一个例外:
Exception thrown: 'System.Runtime.InteropServices.COMException' in BackgroundTask.winmd
WinRT information: Could not create a new view because the main window has not yet been created
据我所知,在添加 UI 元素之前需要一个视图,但我必须 渲染网格并将其保存到图像中后台任务。
以前,我在 Windows Phone 8.1 中毫无问题地实现了这一点..
是否无法在后台任务或非 UI 任务中使用 UI 元素?
如果是,我该怎么做?
我相信你忘记实施 XamlRenderingBackgroundTask
。
Provides the ability to create a bitmap from a XAML tree in a background task.
问题: 我正在尝试用其他一些 UI 元素(主要是文本块)创建一个网格,然后使用 RenderTargetBitmap
渲染网格和最后将其保存到图像文件中,在 后台任务
方法代码如下:
private async Task<bool> RenderGridAsync()
{
Grid mainGrid = new Grid();
TextBlock tText = new TextBlock()
{
HorizontalAlignment = HorizontalAlignment.Left,
TextWrapping = TextWrapping.Wrap,
Text = "Some Example Text",
VerticalAlignment = VerticalAlignment.Top,
FontSize = 72,
FontWeight = FontWeights.SemiLight
};
mainGrid.Children.add(tText);
RenderTargetBitmap rtb = new RenderTargetBitmap();
await rtb.RenderAsync(mainGrid);
var pixelBuffer = await rtb.GetPixelsAsync();
var pixels = pixelBuffer.ToArray();
var displayInformation = DisplayInformation.GetForCurrentView();
var file = await ApplicationData.Current.LocalFolder.CreateFileAsync("CurrentImage" + ".png", CreationCollisionOption.ReplaceExisting);
using (var stream = await file.OpenAsync(FileAccessMode.ReadWrite))
{
var encoder = await BitmapEncoder.CreateAsync(BitmapEncoder.PngEncoderId, stream);
encoder.SetPixelData(BitmapPixelFormat.Bgra8,
BitmapAlphaMode.Premultiplied,
(uint)rtb.PixelWidth,
(uint)rtb.PixelHeight,
displayInformation.RawDpiX,
displayInformation.RawDpiY,
pixels);
await encoder.FlushAsync();
}
}
但是当我从后台任务的 运行() 方法调用此方法时,出现以下错误:
我用谷歌搜索了一下异常,发现为了从非 UI 线程更新 UI 元素,我需要使用这个:
await Windows.ApplicationModel.Core.CoreApplication.MainView.CoreWindow.Dispatcher
.RunAsync(CoreDispatcherPriority.Normal, async () => {
await RenderGridAsync();
});
但即使这样也给了我一个例外:
Exception thrown: 'System.Runtime.InteropServices.COMException' in BackgroundTask.winmd
WinRT information: Could not create a new view because the main window has not yet been created
据我所知,在添加 UI 元素之前需要一个视图,但我必须 渲染网格并将其保存到图像中后台任务。 以前,我在 Windows Phone 8.1 中毫无问题地实现了这一点..
是否无法在后台任务或非 UI 任务中使用 UI 元素? 如果是,我该怎么做?
我相信你忘记实施 XamlRenderingBackgroundTask
。
Provides the ability to create a bitmap from a XAML tree in a background task.