I have copied some functionality / files from one solution to another.
In solution 1 I have Windows Application DemoApp1 that has folders:
Shell
Ribbon/Resources
In Shell/ShellView.xaml
<UserControl.Resources>
<ResourceDictionary>
<ResourceDictionary.MergedDictionaries>
<ResourceDictionary Source="/Ribbon/Resources/Ribbon.xaml"/>
</ResourceDictionary.MergedDictionaries>
</ResourceDictionary>
</UserControl.Resources>
above works with no problem.
In solution 2 I have Windows Application DemoApp2 that does very little. App-class inherits from a class in C# Class Library DemoApp2Feature that does most of the things.
The Shell and Ribbond folder structure and files are the same in Class Library DemoApp2Feature. However here that above results in:
XamlParseException 'Set property 'System.Windows.ResourceDictionary.Source' threw an excetion'.
When I look in VS2015 exception details BaseUri looks like this:
{pack://application:,,,/DemoApp2Feature;component/shell/shellview.xaml}
I would like to keep the files and folder-structure the same also in DemoApp2Feature because there's dozens of files that has these MergedDictionaries-definitions. So how can I tell what is the base for the place where to look for ResourceDictionaries for DemoApp2Feature.
I'm not sure I fully understand your scenario, but this page explains the proper format for pack URIs depending upon where the resource is:
https://msdn.microsoft.com/en-us/library/aa970069(v=vs.110).aspx
Related
I always have problems making new prefixes in xaml. Most of the time, i get the message that the URI cannot be found in the assembly. My setup:
I have a WPF project (in a solution with class libs and asp.NET projects) with a MainWindow.xaml file. The XAML starts with : Window x:Class="MainWindow" ... .
So as default, there's no namespace given to it. In that same project i made a folder "Folder". In that folder, i have resx-files. What i need to do is make a prefix in xaml so i can address those files. I was thinking of :
xmlns:p="clr-namespace:WpfApplication.Folder"
and then for my controls
<Label Content="{x:Static p:NameResxFile.KeyName></Label>
However, the prefix generates the "URI cannot be found in the assembly" error. I'm i just failing at making prefixes?
Thanks in advance.
EDIT
If you cannot make a namespace ref to a folder, what is happening here?
xmlns specifies namespaces, it does not bother with folders or files, if you need access to an external resource you can load it into your control's resources via ResourceDictionary.
There was something like this i think:
<Window.Resources>
<ResourceDictionary x:Key="ExternalRes" Source="Folder/File.xaml"/>
....
</Window.Resources>
To reference an element of resource dictionary you should add that dictionary to your control's Resources collection or register it in the App.xaml file. After that you could just use StaticResource extension to get access to the element. Your code will look like this:
<UserControl.Resources>
<ResourceDictionary>
<ResourceDictionary.MergedDictionaries>
<ResourceDictionary Source="/Folder/NameResxFile.xaml" />
</ResourceDictionary.MergedDictionaries>
</ResourceDictionary>
</UserControl.Resources>
<!-- ... -->
<Label Content="{StaticResource KeyName}"/>
Things get trickier if you want to put the resource dictionary to another assembly and reference it. For this purpose refer to PackURIs in WPF article.
For some reason the following code is giving me an exception.
<Application.Resources>
<ResourceDictionary>
<ResourceDictionary.MergedDictionaries>
<ResourceDictionary Source="/PPCa.Common.Infrastructure;component/Skins/Default.xaml"/>
<ResourceDictionary>
<app:ResourceWrapper x:Key="ResourceWrapper" />
<app:NotOperatorValueConverter x:Key="NotOperatorValueConverter" />
</ResourceDictionary>
</ResourceDictionary.MergedDictionaries>
</ResourceDictionary>
</Application.Resources>
Here is the exception:
System.Windows.Markup.XamlParseException occurred
Message=Failed to assign to property 'System.Windows.ResourceDictionary.Source'. [Line: 11 Position: 44]
LineNumber=11
LinePosition=44
StackTrace:
at System.Windows.Application.LoadComponent(Object component, Uri resourceLocator)
InnerException:
Line 11 is this:
<ResourceDictionary Source="/PPCa.Common.Infrastructure;component/Skins/Default.xaml"/>
Am I somehow merging my dictionaries wrongly?
Why is no one answering my questions? Am I blacklisted or something. People used to help me out quite a bit more. Anyway, I discovered my problem. The exception was a red herring. The problem had nothing to do with my application resource definition. The problem I was having deep inside my resource dictionaries. I was merge-referencing a dictionary inside my dictionary that no longer existed. That was difficult to figure out.
Are these dictionaries in the same XAP? If so, a relative path should work. I have used all relative paths to merge in dictionaries without any issue. Here is an example of mine:
<Application.Resources>
<ResourceDictionary x:Name="appDictionary">
<ResourceDictionary.MergedDictionaries>
<ResourceDictionary x:Name="ControlStylesDictionary"
Source="Resources/Styles/ControlStyles.xaml" />
<ResourceDictionary x:Name="MenuStylesDictionary"
Source="Resources/Styles/MenuStyles.xaml" />
</ResourceDictionary>
</Application.Resources>
That is the only difference I can see in your XAML.
If the dictionary is in another XAP, you need to download the XAP and load the dictionary from there.
I ran into the same problem, same generic error message and found the solution. This appears to be a bug IMHO.
I am building an app for .Net, SL5, WP7.1. To do this I put the code in the .Net app and add source links for the other projects. Works great.
My main app projects are called MyApp.Net, MyApp.SL, and MyApp.WP. However, I make the default namespace and project output for these projects simply MyApp. Again, works great as it should.
I place my resources in projects MyApp.Resources.Net, MyApp.Resources.SL, and MyApp.Resources.WP. There is a bit of a glitch with using the VS source links as Expression Blend wants direct access to the physical files and gets confused when (for example) the MyApp.Resources.WP project contains a source link to a MyStyles.xaml file in the MyApp.Resources.Net projects. Therefore, all my resource projects actually contain physical files. This works fine also, I just have to synch the files manually. No problems so far.
However, for my resource projects I change the namespace and output files to MyApp.Resources. This keeps my application code simple also, regardless the platform it's built for, the namespace is the same.
Yes, I know this is a bit complicated but it allows me to build for 3 platforms (technically 5 if you include Blendability and UnitTesting) all with the same code base.
To continue, if I create a ResourceDictionary as such
<ResourceDictionary Source="/MyApp.Resources;component/Styles/TextStyles.xaml"/>
I get the Failed to assign to property 'System.Windows.ResourceDictionary.Source' etc...
In short, I discovered that if the assembly name contains a '.' this error shows up. For example if I change my project names to simply 'Resources' it works fine. Or if I leave my projects with their default build names of 'MyApp.Resources.WP' it also works fine.
This has nothing to do with changing my resource dll output file names, I change them all day long and it works great, but if they contain a '.' I get the above error. For example, I can change the output name to "MyAppResourceThatWorks" (leaving the project name as MyApp.Resources.WP and load it in App.xaml with
<ResourceDictionary Source="/MyAppResourceThatWorks;component/Styles/TextStyles.xaml"/>
Works great. Change the output name to "MyAppResourcesThatDoNot.Work" and load it with
<ResourceDictionary Source="/MyAppResourceThatDoNot.Work;component/Styles/TextStyles.xaml"/>
Fails.
Yes, I tried changing the assembly properties, etc. etc. It's a load issue with Pack Uri's.
All of the code samples I've found so far reference a Resource Dictionary that's not in a project subfolder (the dictionary is at the root of the project). I have mine in a subfolder, and I can't figure out how to get WPF to find it. This doesn't work...
<Application.Resources>
<ResourceDictionary Source="/Skins/Black/GlossyButtons.xaml"/>
</Application.Resources>
The ASP.Net tilde syntax doesn't seem to work either.
Is this the best way to include a ResourceDictionary in your app so that WPF can find resources? My goal in this particular case is to apply a style defined in GlossyButtons.xaml to all of the buttons in my app.
Try the Pack URI syntax
http://msdn.microsoft.com/en-us/library/aa970069.aspx
<Application.Resources>
<ResourceDictionary Source="pack://application:,,,/Skins/Black/GlossyButtons.xaml"/>
</Application.Resources>
Discovered the problem - WPF couldn't find an assembly referenced in GlossyButtons.xaml, but didn't show the actual error (that there was a problem with the .xaml) until I had compiled and executed several times. The error displayed (at first) was that GlossyButtons.xaml couldn't be located.
That was a little confusing.
Consider a File | New Project of a WPF Application that contains:
A new custom control named CustomControl1
Two new resource dictionaries named Dictionary1 and Dictionary2
Take the generated style out of Generic.xaml and move it to Dictionary2. Then merge Dictionary2 into Dictionary1 and Dictionary1 into Generic like this:
<!--Generic.xaml-->
<ResourceDictionary.MergedDictionaries>
<ResourceDictionary Source="pack://application:,,,/Themes/Dictionary1.xaml"/>
</ResourceDictionary.MergedDictionaries>
<!--Dictionary1.xaml-->
<ResourceDictionary.MergedDictionaries>
<ResourceDictionary Source="Dictionary2.xaml"/>
</ResourceDictionary.MergedDictionaries>
Then, add an instance of CustomControl1 into MainWindow's grid. (This part is necessary to reproduce the issue. The project always compiles fine - only at runtime does the issue show up, and the dictionaries must be referenced.)
In Dictionary1.xaml I am merging in another dict in the same folder, so a simple Source="Dictionary2.xaml" works. Yet in Generic.xaml I must use an absolute URI. If I change the above to be Source="Dictionary1.xaml" without the pack://application stuff then I get a XamlParseException caused by an IOException "Cannot locate resource 'dictionary1.xaml'" when it tries to construct the MainWindow.
My Question: What's special about generic.xaml regarding relative URI resolution, and why?
Excuse me because I have no ability to write comments so I post this as an answer.
I have the same situation and everything works fine for me. I don't need to put "pack://application" in the path in Generic.xaml. But only when the output type of an assembly is "Windows Application".
For "Class library" I need to add assembly name to the path (Source="/ClassLibarayAssemblyName;component/Themes/Dictionary1.xaml") becasue without it WPF engine tries to look for Dictionary1.xaml in application's main assembly.
Target framework in both cases is ".NET Framework 4 Client Profile"
Just a guess: generic.xaml needs to be accessible from outside assemblies as well, so it's a way to ensure that the resources can be found from anywhere, using absolute URIs. As I said, it's just a stab in the dark, not sure.
In my WPF project i keep a user control in a separate library project. The user control accesses resources in a separate XAML file, like this:
<UserControl.Resources>
<ResourceDictionary>
<ResourceDictionary.MergedDictionaries>
<ResourceDictionary Source="/Resources/ViewResources.xaml" />
</ResourceDictionary.MergedDictionaries>
<!-- Local styles here -->
</ResourceDictionary>
</UserControl.Resources>
The resource file, ViewResources.xaml, resides in a folder in the control library project named Resources. It has the default build action (Page) and custom tool (MSBuild:Compile).
The problem is when I reference the control library in my WPF application and use the user control. At runtime, I get the following XamlParseException:
Set property 'System.Windows.ResourceDictionary.Source' threw an exception.
...which wraps the IOException:
Cannot locate resource 'resources/viewresources.xaml'.
How can I fix this? I have tried to change the resource file's build action to "content" and have it copied to the output directory (that works for files and similar "dumb" resources). But to no avail. Also, it doesn't work property in the user control then.
Is there a better way to specify the path?
Will I have to move the resource file to the application project (I'd rather not, as it belongs in the user control's domain).
Found it.
Turns out there is a better way to specify the path, Pack URIs. I changed the XAML to the following:
<UserControl.Resources>
<ResourceDictionary>
<ResourceDictionary.MergedDictionaries>
<ResourceDictionary Source="pack://application:,,,/RoutingManager;component/Resources/ViewResources.xaml" />
</ResourceDictionary.MergedDictionaries>
<!-- Local styles here -->
</ResourceDictionary>
</UserControl.Resources>
and that fixed it.
I thought it was worth posting this just in case anyone else is struggling with the same problem, as I've spent over two hours fighting with syntax, etc. only to find that the solution was dead simple, but not that apparent:
When referencing a packed resource from another control library, it seems to work fine at design time, and even compiles without error, but fails at runtime with the 'Set property 'System.Windows.ResourceDictionary.Source' threw an exception' error. It turns out that simply referencing the resource assembly from your control library is not enough, you ALSO need to add a REFERENCE to the assembly containing the resource dictionary in you main application assembly, else it seems it does not get compiled into the application. (i.e. Startup Application (the one with app.xaml) -> Add Reference -> select assembly with referenced resource file/s).
Hope this helps!
In my case I had the ResourceDictionary and the UserControl on the same Library, but separate from the main application. What worked for me was specifying the name of the assembly in the format Adam suggested in the comment AND I had to change the ResourceDictionary in the project from Embedded Resource to Page. I didn't try using the pack:// format, but I assume it would work too.
<ResourceDictionary Source="/AssemblyName;component/Assets/MyResource.xaml"/>
I had the same error (IOException - file not found), which cost me a day of my life that I'll never get back.
Using neither the simpler "/assemblyname..." nor the "pack://...." syntax worked for me.
I was referencing the resource assembly in my main assembly correctly.
The error disappeared when I changed my xaml resource file Build Action property to "Resource", as mentioned above.
However, I then encountered a XamlParseException at this line:
<ImageBrush x:Key="WindowBackground" ImageSource="Images/gradient.png" />
(which I had hand-typed).
This left the xaml resource file I was trying to include with effectively an invalid dependency.
Oddly the fix was to delete the ImageSource property I had typed, re-insert it BUT select the image from the pulldown menus that appear as a result.
Even though the resulting line appears exactly the same, it clearly isn't.
Starting to dislike WPF (VS2013), but hope this helps.
:0/
I had the same situation, but the Pack URIs didn't help me, I was still getting "Cannot locate resource..." exception in the referencing (executable) project. What helped me, was the setting of my ResourceDictionary files in the custom control library project as Embedded Resource.