在 WPF 应用程序中使用来自 .NET Standard 程序集的内容文件 [英] Use a Content File from a .NET Standard assembly in a WPF application
问题描述
我想在 .NET Standard 程序集中嵌入一个文件,并在 WPF 应用程序的 XAML 中使用它.
如果将构建操作设置为Resource
,在其他程序集中使用嵌入文件非常容易,但必须使用<Project Sdk="Microsoft.NET.Sdk.WindowsDesktop">
和
以便能够像这样使用 Resource
构建操作:
<TargetFramework>netcoreapp3.1</TargetFramework><UseWPF>true</UseWPF></PropertyGroup><项目组><Resource Include="ResourcesImage.png"/></项目组>
然后你可以从另一个程序集中使用这个 Uri:
pack://application:,,,/ReferencedAssembly;component/Resources/Image.png
如下所示:
我的问题:
如果您只想要 <Project Sdk="Microsoft.NET.Sdk">
并且不想要 Content
构建操作,因为它不需要 WPF,如下所示:
https://docs.microsoft.com/en-us/visualstudio/ide/build-actions
并像这样使用它:
<TargetFramework>netstandard2.0</TargetFramework></PropertyGroup><项目组><Content Include="ResourcesImage.png"><CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory></内容></项目组>
然后你应该可以从另一个程序集中使用这个 Uri:
pack://application:,,,/Resources/Image.png
如下所示:
但我得到以下异常:
抛出异常:System.Private.CoreLib.dll 中的System.Resources.MissingManifestResourceException"抛出异常:PresentationFramework.dll 中的System.IO.IOException"抛出异常:PresentationCore.dll 中的System.IO.IOException"System.Windows.Data 错误:6:TargetDefaultValueConverter"转换器无法转换值pack://application:,,,/Resources/Image.png"(类型String");如果可用,将使用回退值.BindingExpression:Path=BackgroundImage;DataItem='NavigationNode' (HashCode=663215);目标元素是 'Image' (Name='');目标属性是源"(类型ImageSource")IOException:System.IO.IOException: 无法找到资源resources/image.png".
我已经清理并重建了整个解决方案.
我做错了什么?
重要提示:我需要在 xaml 中使用包 URI - 太多了,无法将所有现有代码从 xaml 转换为 cs!
如果您引用复制到输出目录的内容文件,您可以使用路径而不是包 URI.试试这个:
image.Source = new BitmapImage(new Uri($@"{System.AppContext.BaseDirectory}ResourcesImage.png",UriKind.Absolute));
如果您出于某种原因仍需要使用包 URI,请将 pack://application:,,,
替换为 pack://siteoforigin:,,,
在路径中,它应该可以工作.
I want to embed a file in a .NET Standard assembly and use it in XAML in a WPF app.
If you set the build action to Resource
it is very easy to use the embedded file in other assemblies, but you have to use <Project Sdk="Microsoft.NET.Sdk.WindowsDesktop">
and <UseWPF>true</UseWPF>
to be able to use the Resource
build action like so:
<PropertyGroup>
<TargetFramework>netcoreapp3.1</TargetFramework>
<UseWPF>true</UseWPF>
</PropertyGroup>
<ItemGroup>
<Resource Include="ResourcesImage.png" />
</ItemGroup>
Then you can use this Uri from another assembly:
pack://application:,,,/ReferencedAssembly;component/Resources/Image.png
as seen here:
My question:
If you want only <Project Sdk="Microsoft.NET.Sdk">
and don't want <UseWPF>true</UseWPF>
then you have to use the Content
build action, because it does not require WPF, as seen here:
https://docs.microsoft.com/en-us/visualstudio/ide/build-actions
And use it like so:
<PropertyGroup>
<TargetFramework>netstandard2.0</TargetFramework>
</PropertyGroup>
<ItemGroup>
<Content Include="ResourcesImage.png">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
</ItemGroup>
Then you should be able to use this Uri from another assembly:
pack://application:,,,/Resources/Image.png
as seen here:
But I get the following exception:
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'.
I have cleaned and rebuilt the whole solution.
What am I doing wrong?
Important: I need to use a pack URI in xaml - too many to convert all existing code from xaml to cs!
If you reference a content file that gets copied to the output directory, you could use a path rather than a pack URI. Try this:
image.Source = new BitmapImage(new Uri($@"{System.AppContext.BaseDirectory}ResourcesImage.png",
UriKind.Absolute));
If you still need to use a pack URI for some reason, replace pack://application:,,,
with pack://siteoforigin:,,,
in the path and it should work.
这篇关于在 WPF 应用程序中使用来自 .NET Standard 程序集的内容文件的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!