2

在我的 WPF 应用程序中,我有一个自定义的 Canvas 实现,其中我使用指定的 .ttf 文件绘制了一些文本。ttf 文件位于一个临时位置,可以在以后的某个时间点删除。我的问题是,一旦我的文本在画布上呈现,ttf 文件似乎保持打开状态,并且在应用程序关闭之前无法删除。似乎是保持字体文件打开的 FormattedText 实例。有谁知道“处理” FormattedText 的方法,或者以任何其他方式确保字体文件在渲染后关闭?

我的文字绘制代码:

public class MyCanvas : System.Windows.Controls.Canvas
{
    protected override void OnRender(DrawingContext dc)
    {
        base.OnRender(dc);

        // Some other drawing stuff...

        FontFamily fontFamily = new FontFamily(fontUri);
        Typeface typeFace = new Typeface(fontFamily, FontStyles.Normal, FontWeights.Normal, FontStretches.Normal);
        FormattedText formattedText = new FormattedText(chars, System.Globalization.CultureInfo.InvariantCulture, FlowDirection.LeftToRight, typeFace, text.FontHeight, new SolidColorBrush(color));
        dc.DrawText(formattedText, new Point(text.X + offsetX, text.Y + offsetY));
        int textWidth = (int) formattedText.Width;
        int textHeight = (int)formattedText.Height;

        // Drawing continues...
    }
}

注意:似乎我什至不必调用DrawText来锁定字体文件(尝试注释掉该行)。使用 formattedText 实例分配 textWidth 和 textHeight 变量足以让 WPF 保持文件打开。

更新: 我无法解决这个问题,所以目前我正在使用一种解决方法,如果覆盖现有字体目录失败,则会创建一个新的临时字体目录。它有效,但我对不得不这样做并不满意,所以我仍然对如何解决这个问题的任何建议感兴趣。

4

1 回答 1

1

也许它在某种程度上与 Pr​​esentation Font Cache 相关,这是一种运行以缓存字体数据结构的服务,以便 WPF 应用程序执行得更好......也许它使文件保持锁定状态。

尝试更改 Presentation Font Cache 服务,使其停止并禁用。运行您的应用程序,然后尝试查看是否可以删除字体文件。

如果实际上是原因,禁用演示字体缓存不是一个长期的解决方案。您可能会以编程方式停止并重新启动它......不确定这将如何影响其他正在运行的 WPF 应用程序。

有一种更明确的方法可以通过使用工具来查看谁锁定了文件,例如

一个可能的解决方案(绕过锁定文件的人)是将 .TTF 文件作为资源放入您的应用程序中,然后您可以让 WPF 担心如何管理和清理它。

链接:

更新:

您可以创建一个包装器类,其工作是在释放对象时删除文件,或者如果由于文件仍处于锁定状态而无法在释放时删除文件,那么当垃圾收集器调用终结器时它将被删除。

另一种可能性是使用FileOptions.DeleteOnClose- 您必须查看是否可以在您打开/创建的字体文件上使用 FontFamily,并且当前正在维护一个打开的文件句柄。

您说“ttf 文件驻留在一个临时位置,可以在以后的某个时间点删除。”...当您在以后的某个时间点说...我假设是当您退出程序/进程时....或者不是这样吗?

或尝试 TempFileCollection:

于 2012-07-24T21:32:55.900 回答