在C# WPF应用程序中访问资源(同一程序集)

5
(在深入了解之前,我想先介绍一下背景:我正在尝试加载一个WPF框架,其中包含我作为资源包含在项目中的.html文件的内容。)
我创建了一个新的WPF应用程序;我向项目中添加了一个名为“foofiles”的新文件夹,并添加了一些文件(page1.foo和page2.foo)到该文件夹中。
对于每个新添加的.foo文件,我右键单击它,进入“属性”,将构建操作设置为“资源”,并将输出目录设置为“始终复制”。
我希望能够在XAML中访问这些文件:
<Frame x:Name="bar" Source="/foofiles/page1.foo"/>

而在过程式代码中:

private void someFunc()
{
    bar.Source = new Uri("/foofiles/page1.foo");
}

但我就是想不明白为什么这个不起作用——我收到了一个“无法确定URI格式”的错误信息。

在代码后台,我尝试做了这个:

private void someFunc()
{
    bar.Source = new Uri("pack://application:,,,/foofiles/page1.foo");
}

代码没有抛出异常,但我的主窗口崩溃了。

按照我的思路,如果我在项目中添加任何类型的文件,并将其标记为“资源”(在“生成操作”中),那么我应该能够像上面的示例一样使用该文件。此外,我想这样使用该文件:

private void someOtherFunc()
{
    System.IO.StreamReader reader = new System.IO.StreamReader("/foofiles/page1.foo");
    string bar = reader.ReadToEnd();
}

任何帮助都将不胜感激...提前致谢!

1个回答

8
尝试将“组件”部分添加到您的Pack URI中,如下所示。
pack://application:,,,/AssemblyName;component/ResourceName

其中AssemblyName是您程序集的名称。所以在您的情况下,以下语句应该可行:

bar.Source = new Uri("pack://application:,,,/AssemblyName;component/foofiles/page1.foo");

更实际的方法是尝试使用相对包URI表示法:
bar.Source = new Uri("AssemblyName;component/foofiles/page1.foo", UriKind.Relative)); 

读取流式资源时,请使用以下方法

var streamResourceInfo = Application.GetResourceStream(uri);
using (var stream = streamResourceInfo.Stream)
{
   // do fancy stuff with stream
}

请注意,Pack Uris 是 WPF 特有的,因此 StreamReader 不知道它们。 - mkoertgen
感谢您的回复...您上次展示如何流式读取资源的代码片段非常有效!(不幸的是,在加载Frame.Source时,两种变体的Uri构建都会在System.dll中引发System.NotImplementedException。不过,我刚刚想到了如何在CLR异常上打断点,并且我将尝试解决这个问题。再次感谢!) - Literata
事实证明,我的问题涉及到上下文——WPF不允许您从html文件资源加载frame.Source。(您可以使用“siteoforigin”来完成,但这意味着您正在从与您的程序集外部文件获取数据。)非常感谢您! - Literata
不用谢。我之前并不知道WPF不允许加载框架源。很高兴我的回答能够帮到你(至少部分地)。 - mkoertgen

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接