gpt4 book ai didi

wpf - 我的 URI 必须这么长和明确吗?

转载 作者:行者123 更新时间:2023-12-01 15:21:15 24 4
gpt4 key购买 nike

我正在使用 Microsoft Prism 和 Unity 编写一个模块化应用程序。我的应用程序的 Shell 项目加载各种 DLL,它们都包含自己的/resources 或/images 文件夹和用户界面 View 。因此,每个模块都是一个 DLL。

当我试图在我的应用程序中使用资源时,似乎我必须非常明确地说明它的位置才能使其工作。例如,要在同一模块/dll 中定位图像:

<Image Source="pack://application:,,,/MyCompany.MyProduct.MyModule;Component/Images/ZoomIn.gif" />

我真的必须每次都使用 URI 的长格式版本吗?我试过更短的版本,例如:

pack://application:,,,/Images/ZoomIn.gif

Images/ZoomIn.gif

ZoomIn.gif

等等

我想也许那里的第二个版本应该可以工作。当我看到 Uri 示例时,他们经常说“相对于当前程序集”。这是正在运行的可执行文件的程序集吗?或者这是代码所属的程序集(我的库/模块)?

更新:

在 Peter Hansen 的帮助下,我能够将其缩短为:

<Image Source="../Images/ZoomOut.png" />

显然我必须使用 ../因为我的 View 位于子文件夹中。我也可以不使用 pack://语法,因为类型转换器会帮我做这件事。

最佳答案

在 WPF 中检索二进制资源时,有几个不同的选项,它们都取决于您想要哪种行为。

  1. 如果您的资源应该嵌入程序集中,请将它们添加到 Visual Studio 中的项目,并将构建操作设置为资源。这样它们将被烘焙到程序集中,因此不能轻易更改。

  2. 如果它们应该作为松散文件保留,请将它们添加到项目中,并将Build Action 设置为Content。还要确保它们被复制到输出目录。这是一个好主意,如果您需要经常替换它们,并且不想每次都重新编译程序集。

  3. 如果您希望将它们作为松散文件,但出于某种原因不想将它们包含在您的 Visual Studio 解决方案中(可能在编译时不知道它们),您可以使用完整路径或使用一种叫做 SiteOfOrigin 符号的东西。我不会讨论这个,因为这与您的情况无关。

要从您的代码访问资源,您可以使用 Pack URI,它可以有不同的形式:

  • pack://application:,,,/img.jpg
    在项目的根目录中引用图像。

  • pack://application:,,,/Folder1/Folder2/img.jpg
    引用项目子文件夹中的图像。

  • pack://application:,,,/NameOfDll;Component/img.jpg
    在 Visual Studio 中有引用的不同程序集中引用图像。

幸运的是,当从 XAML 引用资源时,无需编写完整的 URI。
基本上可以避免 pack://application:,,, 部分,因为存在一个 TypeConverter 可以将部分位置转换为完整的 URI。

对于上面的第 1 点和第 2 点,相同的 XAML 用于引用资源,无论它们在执行时作为松散文件与程序集一起存在还是嵌入其中。

不过,在从过程代码中引用资源时,必须使用完全定义的显式 URI。

我已经编写了一些代码并包含了一些图像,以展示其工作原理。

Image showing running program Image of solution explorer view

相关 XAML:

<StackPanel>
<TextBlock Text="Embedded in same assembly" />
<Image Source="gift.png" />
</StackPanel>

<StackPanel>
<TextBlock Text="Embedded in same assembly in a subfolder" />
<Image Source="Content/Images/gift.png" />
</StackPanel>

<StackPanel>
<TextBlock Text="Embedded in same assembly in a subfolder using full pack URI format" />
<Image Source="pack://application:,,,/Content/Images/gift.png" />
</StackPanel>

<StackPanel>
<TextBlock Text="Embedded in different assembly" />
<Image Source="/Module1;Component/gift.png" />
</StackPanel>

<StackPanel>
<TextBlock Text="Embedded in different assembly in a subfolder" />
<Image Source="/Module1;Component/Images/gift.png" />
</StackPanel>

<StackPanel>
<TextBlock Text="Embedded in different assembly in a subfolder using full Pack URI format" />
<Image Source="pack://application:,,,/Module1;Component/Images/gift.png" />
</StackPanel>

<StackPanel>
<TextBlock Text="Setting imagesource from code-behind" />
<Image x:Name="image1" />
</StackPanel>

相关代码隐藏:

public Window1()
{
InitializeComponent();

//Here we have to use the full Pack URI
//image1.Source = new BitmapImage(new Uri("/Module1;Component/Images/gift.png")); //Throws exception..
image1.Source = new BitmapImage(new Uri("pack://application:,,,/Module1;Component/Images/gift.png"));
}

更新
当资源在使用它的同一个程序集中时,没有理由包含 URI 的 /NameOfDll;Component/ 部分。我不确定为什么它在您的情况下不起作用。

我在 Module1 中添加了一个 Window,它只引用其自己的程序集中的单个图像,而且似乎工作正常。在 WPF 应用程序中单击按钮时显示窗口。

<Window x:Class="Module1.WindowTest"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
mc:Ignorable="d"
d:DesignHeight="300" d:DesignWidth="300"
Title="Window from Module1">
<Grid>
<Image Source="Images/gift.png" />
</Grid>
</Window>

Showing different window with resource shown

关于wpf - 我的 URI 必须这么长和明确吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13480696/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com