wpf WPF在多层/项目应用解决方案中集中xaml/image资源
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/13665120/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
WPF Centralize xaml/image Resources in Multi-Tier/Project Application Solution
提问by akagixxer
My situation is this. I have multiple projects under a WPF solution which make up a multi-tier application I am developing. Since separate projects will sometimes need to access the same image or xaml resource I'd like to centralize "Public" resources to one project that can be referenced by any other projects requiring these "Public" resources. For example, I have a BMP image that I use in various controls and windows in separate projects that serves as a banner/logo. It seems like I should be able to add this image as a resource to the public resources project and reference it from my other projects instead of adding the image separately to every project that needs it. If this is possible, what would it look like and how should I go about doing it? If my idea just sucks I'm open to suggestions, but the project is going to be quite large so I don't want to be adding resources all over the place.
我的情况是这样。我在 WPF 解决方案下有多个项目,这些项目构成了我正在开发的多层应用程序。由于不同的项目有时需要访问相同的图像或 xaml 资源,我想将“公共”资源集中到一个项目中,该项目可由需要这些“公共”资源的任何其他项目引用。例如,我有一个 BMP 图像,我在不同项目中的各种控件和窗口中使用它作为横幅/徽标。似乎我应该能够将此图像作为资源添加到公共资源项目中并从我的其他项目中引用它,而不是将图像单独添加到每个需要它的项目中。如果这是可能的,它会是什么样子,我应该如何去做?如果我的想法很糟糕,我愿意接受建议,
Thanks!
谢谢!
P.S. I have searched this topic quite a bit but there are so many garbage answers out there from people that don't know what they are doing. Given that I'm relatively new to WPF I'd rather get a direct answer to my problem.
PS 我已经搜索了很多这个主题,但是有很多来自不知道自己在做什么的人的垃圾答案。鉴于我对 WPF 比较陌生,我宁愿直接回答我的问题。
回答by akagixxer
Well after some tinkering and research I found a solution to my own question. It seems like bits and pieces of my answer were scattered all over the web so I'll try to explain the whole thing at once, in one place. To re-cap I basically wanted to centralize any resources used across projects within my solution. These are the steps I eventually followed to accomplish this.
经过一些修补和研究,我找到了我自己问题的解决方案。似乎我的回答的点点滴滴散布在整个网络上,因此我将尝试在一个地方立即解释整个事情。概括地说,我基本上想将我的解决方案中跨项目使用的所有资源集中起来。这些是我最终为实现这一目标而遵循的步骤。
1. Create a User Control project in your solution (any project that can host Resource Dictionaries will do). I'll refer to this project as "the resource project".
1. 在您的解决方案中创建一个用户控制项目(任何可以托管资源词典的项目都可以)。我将把这个项目称为“资源项目”。
2. Add any resource files (images etc...) that you want to share between projects to the resource project. I try to organize files in sub-directories that make sense. You will want to set the build action to "Resource" so that it gets compiled into the output binary.
2. 将要在项目之间共享的任何资源文件(图像等...)添加到资源项目。我尝试在有意义的子目录中组织文件。您需要将构建操作设置为“Resource”,以便将其编译为输出二进制文件。
3. Now add a resource dictionary to the resource project. In my case I wanted to reference several images so I made one called "ImageDictionary.xaml".
3. 现在将资源字典添加到资源项目中。就我而言,我想引用几张图片,所以我制作了一张名为“ImageDictionary.xaml”的图片。
4. Add references to the image files in the resource dictionary. I am referencing images here but its just a resource dictionary, you can put whatever in there. The string in the middle is just the relative path to the image file you are referring to.
4. 在资源字典中添加对图像文件的引用。我在这里引用图像,但它只是一个资源字典,你可以在那里放任何东西。中间的字符串只是您所指图像文件的相对路径。
<ImageSource x:Key="SomeImageKey">
Images/SomeImage.bmp
</ImageSource>
5. Now go to a project that requires the resource dictionary you just made in step 4. It can be another user control or a window, whatever. Right-click on project references and add a reference to the resource project.
5. 现在转到需要您在第 4 步中创建的资源字典的项目。它可以是另一个用户控件或窗口,等等。右键单击项目引用并添加对资源项目的引用。
6. Okay now the current project needs to reference the dictionary you made in step 4 that is defined in the resource project. I made a user control first so this is what my code would look like below... Note that I used merged dictionaries. I plan on using more later so I chose this way instead of a single dictionary. "ResourceProject" below is the name of the project/assembly that you added the resource to. "component" is a keyword that needs to be there, followed by the path to the dictionary xaml code file.
6. 好的,现在当前项目需要引用您在第 4 步中创建的资源项目中定义的字典。我首先创建了一个用户控件,所以这就是我的代码如下所示...请注意,我使用了合并词典。我打算以后使用更多,所以我选择了这种方式而不是单个字典。下面的“ResourceProject”是您添加资源的项目/程序集的名称。“component”是需要存在的关键字,后跟字典xaml代码文件的路径。
<UserControl.Resources>
<ResourceDictionary>
<ResourceDictionary.MergedDictionaries>
<ResourceDictionary Source="/ResourceProjectAssembly;component/Resources/ImageDictionary.xaml" />
</ResourceDictionary.MergedDictionaries>
</ResourceDictionary>
</UserControl.Resources>
As you can see, referencing an external resource dictionary requires something called a "Pack URI". I found a short hand way of doing it. The long way is quite a bit uglier and as far as I know, there is no advantage to it. But here is what the long way looks like.
如您所见,引用外部资源字典需要称为“Pack URI”的东西。我找到了一种简捷的方法。长路有点丑,据我所知,它没有任何优势。但这是长路的样子。
<UserControl.Resources>
<ResourceDictionary>
<ResourceDictionary.MergedDictionaries>
<ResourceDictionary Source="pack://application:,,,/ResourceProjectAssembly;component/Resources/ImageDictionary.xaml" />
</ResourceDictionary.MergedDictionaries>
</ResourceDictionary>
</UserControl.Resources>
7. Now that your current project has a reference to the resource dictionary in the resource project, you can use anything from that dictionary. I went ahead and put an image in my user control. Below is the code. Its just like referencing a dictionary locally.
7. 现在您的当前项目已经引用了资源项目中的资源字典,您可以使用该字典中的任何内容。我继续在我的用户控件中放置了一个图像。下面是代码。就像在本地引用字典一样。
<Image Source="{StaticResource SomeImageKey}" />
8. Important Note! This caused me a headache for a while before I found it. Make sure that the startup project in your solution has a reference to the resource project EVEN IF THE STARTUP PROJECT DOES NOT USE THE RESOURCE PROJECT. (I.e. right-click references, add reference etc...) The resources will not get compiled into the output unless you do this. This part was tricky because the designer was even showing my images and I had no xaml errors but at runtime it would throw set property and cannot find file exceptions. This went away when I referenced my resource project from my startup project.
8. 重要提示!这让我头疼了一阵子才发现。确保您的解决方案中的启动项目引用资源项目,即使启动项目不使用资源项目。(即右键单击引用、添加引用等...)除非您这样做,否则资源将不会编译到输出中。这部分很棘手,因为设计师甚至展示了我的图像,我没有 xaml 错误,但在运行时它会抛出 set 属性并且找不到文件异常。当我从我的启动项目中引用我的资源项目时,这种情况就消失了。
Hopefully this helps somebody. Below are some links to a few places (including stackoverflow) that gave me what I needed to put all the pieces together.
希望这对某人有帮助。下面是一些地方(包括 stackoverflow)的一些链接,它们为我提供了将所有部分放在一起所需的内容。
Load WPF styles or other Static Resources from an external file or assembly

