wpf - 在 WPF 中创建 XPS - 使用的图像文件将被锁定,直到我的应用程序退出

标签 wpf flowdocument xps file-locking

在我的 WPF 应用程序中,我正在创建一个 FlowDocument通过将其 XAML 标记构建为字符串,然后使用 XamlReader.Parse将字符串转换为 FlowDocument对象,然后我将其保存到 XPS 文档文件中。它有效。

我需要在文档中包含图像,因此为了实现此目的,我在临时目录中创建并保存图像作为临时文件,然后在我的 FlowDocument 中使用绝对路径引用它。的 XAML。这也有效 - 在 XPS 文档创建过程中,图像实际上嵌入到 XPS 文档中,这很棒。

但问题是,我的应用程序在此图像上保留文件锁定,直到应用程序退出。

我正在清理所有资源。我生成的 XPS 文件没有文件锁定 - 只有图像文件。如果我注释掉创建 XPS 文件的代码部分,则图像文件不会被锁定。

我的代码(我使用 .NET 4 CP):

var xamlBuilder = new StringBuilder();

// many lines of code like this
xamlBuilder.Append(...);

// create and save image file
// THE IMAGE AT THE PATH imageFilePath IS GETTING LOCKED
// AFTER CREATING THE XPS FILE
var fileName = string.Concat(Guid.NewGuid().ToString(), ".png");
var imageFilePath = string.Format("{0}{1}", Path.GetTempPath(), fileName);
using (var stream = new FileStream(imageFilePath, FileMode.Create)) {
  var encoder = new PngBitmapEncoder();
  using (var ms = new MemoryStream(myBinaryImageData)) {
    encoder.Frames.Add(BitmapFrame.Create(ms));
    encoder.Save(stream);
  }
  stream.Close();
}

// add the image to the document by absolute path
xamlBuilder.AppendFormat("<Paragraph><Image Source=\"{0}\" ...", imageFilePath);

// more lines like this
xamlBuilder.Append(...);

// create a FlowDocument from the built string
var document = (FlowDocument) XamlReader.Parse(xamlBuilder.ToString());

// set document settings
document.PageWidth = ...;
...

// save to XPS file
// THE XPS FILE IS NOT LOCKED. IF I LEAVE OUT THIS CODE
// AND DO NOT CREATE THE XPS FILE, THEN THE IMAGE IS NOT LOCKED AT ALL
using (var xpsDocument = new XpsDocument(filePath, FileAccess.ReadWrite)) {
  var documentWriter = XpsDocument.CreateXpsDocumentWriter(xpsDocument);
  documentWriter.Write(((IDocumentPaginatorSource) document).DocumentPaginator);
  xpsDocument.Close();
}

(实际上,它是临时目录中动态生成的图像这一事实是无关紧要的 - 如果我在计算机上的任何图像文件的路径中进行硬编码,则会出现此问题 - 它将被锁定。)

人们可能会认为 XPS 创建代码中存在导致文件锁定的错误。

还有什么我可以尝试的吗?或者通过代码解除文件锁定的方法?

最佳答案

您可以像这样更改您的 xaml:

<Image>
    <Image.Source>
        <BitmapImage CacheOption="None" UriSource="your path" />
    </Image.Source>
</Image>

能够使用 CacheOption 参数,指定 Xaml Builder 应如何加载图像文件,因为默认值似乎会锁定它(等待 GC似乎完成了它的工作)。

这里有一些相关的问题:How do you make sure WPF releases large BitmapSource from Memory?

关于wpf - 在 WPF 中创建 XPS - 使用的图像文件将被锁定,直到我的应用程序退出,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10422992/

相关文章:

wpf - SQL Server CE 上的 Entity Framework 无需安装驱动程序

c# - 如何更改 FlowDocumentReader 中选定文本的选择背景颜色

c# - 无论如何将 RDL 报告内容加载到 WPF FlowDocument 或类似文件中?

c# - 如何枚举 XPS 文件中的资源?

c# - 通过 Microsoft XPS Document Writer 将 PDF 转换为 XPS

c# - 如何动态创建xps文件?

c# - 数据库表的 Entity Framework 和本地缓存

c# - 在 WPF-Desktop 程序中设置每像素位数

wpf - 在文本框功能中提供按钮,不使用自定义控件但覆盖文本框模板

c# - 如何在 WPF UI 中使 <UIElement> 可交互或可点击