在 WPF 应用程序中使用 .NET Standard 程序集中的内容文件

Posted

技术标签:

【中文标题】在 WPF 应用程序中使用 .NET Standard 程序集中的内容文件【英文标题】:Use a Content File from a .NET Standard assembly in a WPF application 【发布时间】:2020-09-05 06:07:43 【问题描述】:

我想在 .NET Standard 程序集中嵌入一个文件,并在 WPF 应用程序的 XAML 中使用它。

如果您将构建操作设置为Resource,那么在其他程序集中使用嵌入文件非常容易,但是您必须使用<Project Sdk="Microsoft.NET.Sdk.WindowsDesktop"><UseWPF>true</UseWPF> 才能使用Resource 构建操作,例如所以:

  <PropertyGroup>
    <TargetFramework>netcoreapp3.1</TargetFramework>
    <UseWPF>true</UseWPF>
  </PropertyGroup>

  <ItemGroup>
    <Resource Include="Resources\Image.png" />
  </ItemGroup>

然后你可以从另一个程序集中使用这个 Uri:

pack://application:,,,/ReferencedAssembly;component/Resources/Image.png

如下所示:

https://docs.microsoft.com/en-us/dotnet/framework/wpf/app-development/pack-uris-in-wpf#resource-file-pack-uris

我的问题:

如果您只需要&lt;Project Sdk="Microsoft.NET.Sdk"&gt; 而不需要&lt;UseWPF&gt;true&lt;/UseWPF&gt;,那么您必须使用Content 构建操作,因为它不需要WPF,如下所示:

https://docs.microsoft.com/en-us/visualstudio/ide/build-actions

然后像这样使用它:

  <PropertyGroup>
    <TargetFramework>netstandard2.0</TargetFramework>
  </PropertyGroup>

  <ItemGroup>
    <Content Include="Resources\Image.png">
      <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
    </Content>
  </ItemGroup>

那么你应该可以从另一个程序集中使用这个 Uri:

pack://application:,,,/Resources/Image.png

如下所示:

https://docs.microsoft.com/en-us/dotnet/framework/wpf/app-development/pack-uris-in-wpf#content-file-pack-uris

但我得到以下异常:

Exception thrown: 'System.Resources.MissingManifestResourceException' in System.Private.CoreLib.dll
Exception thrown: 'System.IO.IOException' in PresentationFramework.dll
Exception thrown: 'System.IO.IOException' in PresentationCore.dll
System.Windows.Data Error: 6 : 'TargetDefaultValueConverter' converter failed to convert value 'pack://application:,,,/Resources/Image.png' (type 'String'); fallback value will be used, if available. BindingExpression:Path=BackgroundImage; DataItem='NavigationNode' (HashCode=663215); target element is 'Image' (Name=''); target property is 'Source' (type 'ImageSource') IOException:'System.IO.IOException: Cannot locate resource 'resources/image.png'.

我已经清理并重建了整个解决方案。

我做错了什么?

重要提示:我需要在 xaml 中使用包 URI - 太多,无法将所有现有代码从 xaml 转换为 cs!

【问题讨论】:

【参考方案1】:

如果您引用复制到输出目录的内容文件,您可以使用路径而不是包 URI。试试这个:

image.Source = new BitmapImage(new Uri($@"System.AppContext.BaseDirectory\Resources\Image.png",
    UriKind.Absolute));

如果由于某种原因您仍需要使用包 URI,请将路径中的 pack://application:,,, 替换为 pack://siteoforigin:,,,,它应该可以工作。

【讨论】:

谢谢,我知道了。但我绝对需要在 xaml 中使用包 URI。 为什么?如果将内容复制到输出目录,则使用包 URI 毫无意义。 我同意,如果你开发一个新的应用程序是没有意义的。但是我正在移植一个 .NET Framework 应用程序,其中包含数百个在 xaml 中具有包 URI 的图像 - 并将所有这些图像从 xaml 转换为 image.Source = new BitmapImage 将是一场噩梦 - 我更愿意为所有这些图像使用 RegEx 替换。无论如何,我发现虽然pack://application:,,, 不能与&lt;Content&gt; 一起使用,但pack://siteoforigin:,,, 可以完美运行,所以我可以删除这个问题......或者把它留给有同样问题的其他人。 @Jinjinov:我在答案中添加了这个,以防你想接受它。

以上是关于在 WPF 应用程序中使用 .NET Standard 程序集中的内容文件的主要内容,如果未能解决你的问题,请参考以下文章

如何在 WPF 应用程序中使用 App.config 进行 log4net 配置

是否可以在 WPF Net 6 应用程序中使用 FolderBrowserDialog?

无法在通用 Windows 或 WPF 应用程序中引用 .NET Core 类库

正确支持WPF的混淆器

WPF 应用程序可以在带有 .Net Core 3 的 Linux 或 Mac 中运行吗?

有没有办法用 .Net 3.5 在 WPF 中模拟 UseLayoutRounding