Shared library not seeing resource dictionary - c#

I have two wpf solutions that use the same class library (one I have written). The library references sytles (as static resources) that are in a resource dictionary of the main project. In one of those solutions, the library finds these static resources in the resource dictionary but in the other project the static resources are not resolved. In both cases the Resource dictionary is declared in the App.Xaml of the main application as follows:
<Application.Resources>
<ResourceDictionary>
<ResourceDictionary.MergedDictionaries>
<ResourceDictionary>
<local:AppBootstrapper x:Key="bootstrapper" />
</ResourceDictionary>
<ResourceDictionary Source="StoryMakerStyle.xaml" />
<ResourceDictionary Source="Resources\GlassButton.xaml"/>
<ResourceDictionary Source="Resources\Slider.xaml" />
</ResourceDictionary.MergedDictionaries>
</ResourceDictionary>
</Application.Resources>
Where StoryMakerStyle.xaml is the name of the resource dictionary in one app. It is called FlashcardsStyle.xaml in the other. The other 2 ResourceDictionary references are the same in both solutions.
Any suggestions as to why references to the resource dictionary are resolved in one solution but not the other?
Thanks in advance

I'm assuming that this is a solution of 2 project. You need to specify which project when referencing the ResourceDictionaries like so:
<ResourceDictionary Source="/ProjectNamespace;Resources/GlassButton.xaml"/>
<ResourceDictionary Source="/ProjectNamespace;Resources\Slider.xaml" />

Related

XAML Designer error: "IOException: Cannot locate resource" - How to provide a Pack URI that works with dynamic assembly name?

We have a ResourceDictionary being referenced as follows
<UserControl.Resources>
<ResourceDictionary>
<ResourceDictionary.MergedDictionaries>
<ResourceDictionary Source="pack://application:,,,/Theming/AppTheme.xaml" />
</ResourceDictionary.MergedDictionaries>
</ResourceDictionary>
</UserControl.Resources>
This works great at runtime. However, the Designer in Visual Studio gives an error in views that reference this UserControl:
IOException: Cannot locate resource 'theming/apptheme.xaml'.
Other SO answers have suggested referencing the ResourceDictionary by specifying the assembly name:
<ResourceDictionary Source="pack://application:,,,/MyDomain.MyApp.Wpf;component/Theming/AppTheme.xaml" />
This makes the Designer happy, but our assembly name is different in staging vs. production, so it would be nice if we didn't have to specify the assembly name. My question is: How can we provide a ResourceDictionary Source URI that makes the Designer happy and does not require specifying the assembly name?
If this is not possible, we might make the URI a static value that is different per build configuration using preprocessor directives.
You can define the UI or resources for your app using XAML.
Resources are typically definitions of some object that you expect to use more than once. To refer to a XAML resource later, you specify a key for a resource that acts like its name.
You can reference a resource throughout an app or from any XAML page within it.
You can define your resources using a ResourceDictionary element from the Windows Runtime XAML.
Then, you can reference your resources by using a StaticResource markup extension or ThemeResource markup extension.
Resources don't have to be strings.
they can be any shareable object, such as styles, templates, brushes, and colors. However, controls, shapes, and other FrameworkElements are not shareable, so they can't be declared as reusable resources.
Example:
<Page.Resources>
<x:String x:Key="key1">Hey</x:String>
<x:String x:Key="key2">Nice</x:String>
</Page.Resources>
you can use those resoures by addressing the keys in their proper location i.e.:
<Label Text="{StaticResource key1}" FontSize="Large" VerticalAlignment="Center"/>
Well, In order to make your project more organized you need to make a ResourceDictionary a seperate file and call it like this (ContentPage part is depending on the page):
<ContentPage.Resources>
<ResourceDictionary>
<ResourceDictionary.MergedDictionaries>
<ResourceDictionary Source="Styles.xaml" />
</ResourceDictionary.MergedDictionaries>
</ResourceDictionary>
</ContentPage.Resources>
// in this example Styles is in the same folder has the page you can make dynamic resource to access it from all areas or make a path in a proper manner like:
xmlns:themes = "clr-namespace:AppName.Themes;assembly=AppName"
How can we provide a ResourceDictionary Source URI that makes the Designer happy and does not require specifying the assembly name?
you make a dynamic one.
like this:
<?xml version="1.0" encoding="utf-8" ?>
<ResourceDictionary
x:Class="App.Themes.Theme"
xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml">
<Color x:Key="PrimaryColor">#ffffff</Color>
<Color x:Key="PrimaryDarkColor">#0f0f0f</Color>
</ResourceDictionary>
and in app.xaml you do this (if Theme is in folder Themes in main project):
<Application xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
xmlns:themes = "clr-namespace:YourProjectName.Themes;assembly=YourProjectName"
x:Class="YourProjectName.App">
<Application.Resources>
<ResourceDictionary>
<ResourceDictionary.MergedDictionaries>
<themes:Theme />
</ResourceDictionary.MergedDictionaries >
</ResourceDictionary>
</Application.Resources>
then you can do stuff like this anywhere:
BackgroundColor="{DynamicResource PrimaryColor}"
Good Luck!

UWP - Reference StaticResource from different style resource dictionary: Failed to assign to property 'Windows.UI.Xaml.ResourceDictionary.Source'

Hello my team and I recently started developing an win10 uwp application. Application will have a lot of views and components so heavy use of styles is expected, so we need to organize our styles through file/folder structure we did this using following structure (unfortunately I cannot embed images yet see the link):
Anyways my Resource.xaml merges all other dictionaries as following:
<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
<ResourceDictionary.MergedDictionaries>
<ResourceDictionary Source="/Resources/Colors.xaml" />
<ResourceDictionary Source="/Resources/Icons.xaml" />
<ResourceDictionary Source="/Resources/Fonts.xaml" />
<ResourceDictionary Source="/Resources/Converters.xaml" />
<ResourceDictionary Source="/Resources/Buttons.xaml" />
<ResourceDictionary Source="/Resources/RadioButton.xaml" />
</ResourceDictionary.MergedDictionaries>
</ResourceDictionary>
And in my App.xaml I reference this dictionary:
<Application.Resources>
<ResourceDictionary>
<ResourceDictionary.MergedDictionaries>
<ResourceDictionary Source="Resources/Resources.xaml" />
</ResourceDictionary.MergedDictionaries>
<vm:ViewModelLocator x:Key="Locator" d:IsDataSource="True" />
</ResourceDictionary>
</Application.Resources>
Now I managed to find the source of the problem in my RadioButton.xaml I reference a brush defined in Colors.xaml using StaticResource lookup:
<Setter Property="Foreground" Value="{StaticResource TopMenuTextBrush}" />
If I remove this line everything will start but with it I get following exception:
Exception {Windows.UI.Xaml.Markup.XamlParseException: The text associated with this error code could not be found.
Failed to assign to property
'Windows.UI.Xaml.ResourceDictionary.Source' because the type
'Windows.Foundation.String' cannot be assigned to the type
'Windows.Foundation.Uri'. [Line: 28 Position: 37]} System.Exception
{Windows.UI.Xaml.Markup.XamlParseException}
Interesting thing is when I start the app with this line commented and uncomment it visual studio will recognize the brush and apply it correctly, it only breaks on application start.
We used same approach before when developing WPF, so I'm thinking it might have to do with something regarding application deployment.
All help is greatly appreciated.
Exception = {Windows.UI.Xaml.Markup.XamlParseException: The text associated with this error code could not be found.
The problem is that you have used wrong ResourceDictionary source . I found the Resources.xaml and other xaml file stored in the same level directory in your screenshot. So you could not declare the parent directory of these xaml files within source. Please modify ResourceDictionary like the following
<ResourceDictionary Source="Colors.xaml"/>
For more you could refer to ResourceDictionary and XAML resource references.

How to add PresentationFramework.Aero theme to ResourceDictionary

I want to add the PresentationFramework.Aero theme to my ResourceDictionary.
The ResourceDictionary itself is in one assembly called ProjectResources. Within this assembly I define all my styles for my project. So this ResourceDictionary is used by several different assemblies in my project. So far it worked fine for all my Dictionaries defined.
Now i want to add the Aero theme. But I always get the exception:
An unhandled exception of type
'System.Windows.Markup.XamlParseException' occurred in
PresentationFramework.dll
Inner Exception:
{"Could not load file or assembly 'PresentationFramework.Aero,
Culture=neutral' or one of its dependencies. The system cannot find
the file specified.":"PresentationFramework.Aero, Culture=neutral"}
The ResourceDictionary is defined like that:
<Application.Resources>
<ResourceDictionary>
<ResourceDictionary.MergedDictionaries>
<ResourceDictionary Source="pack://application:,,,/ProjectResources;component/ProjectResources/Dictionaries/ImageDefinition.xaml"/>
<ResourceDictionary Source="pack://application:,,,/ProjectResources;component/ProjectResources/Dictionaries/Brushes.xaml"/>
<ResourceDictionary Source="pack://application:,,,/ProjectResources;component/ProjectResources/Dictionaries/StylesLabel.xaml"/>
<ResourceDictionary Source="pack://application:,,,/ProjectResources;component/ProjectResources/Dictionaries/StylesTextBox.xaml"/>
<ResourceDictionary Source="pack://application:,,,/ProjectResources;component/ProjectResources/Dictionaries/StylesButton.xaml"/>
<ResourceDictionary Source="pack://application:,,,/ProjectResources;component/ProjectResources/Dictionaries/StylesTabControl.xaml"/>
<ResourceDictionary Source="pack://application:,,,/ProjectResources;component/ProjectResources/Dictionaries/StylesTextBox.xaml"/>
<ResourceDictionary Source="pack://application:,,,/ProjectResources;component/ProjectResources/Dictionaries/StylesBorder.xaml"/>
<ResourceDictionary Source="pack://application:,,,/ProjectResources;component/ProjectResources/Dictionaries/StylesListView.xaml"/>
<ResourceDictionary Source="pack://application:,,,/ProjectResources;component/ProjectResources/Dictionaries/StylesWindow.xaml"/>
<ResourceDictionary Source="pack://application:,,,/ProjectResources;component/ProjectResources/Dictionaries/StylesIndicator.xaml"/>
<ResourceDictionary Source="pack://application:,,,/ProjectResources;component/ProjectResources/Dictionaries/StylesSearchBox.xaml"/>
<ResourceDictionary Source="pack://application:,,,/ProjectResources;component/ProjectResources/Dictionaries/StylesTreeView.xaml"/>
<ResourceDictionary Source="/PresentationFramework.Aero;component/themes/Aero.NormalColor.xaml"/>
</ResourceDictionary.MergedDictionaries>
</ResourceDictionary>
</Application.Resources>
I have also added the reference to PresentationFramework.Aero.dll.
So I don't understand why it cant find the defined theme.
What is the problem with this definition? Did I miss anything else beside this definition to be able to use the theme?
SOLVED:
As toumir said in his comment.
You need to set the parameter
Copy Local = true
of the PresentationFramework.Aero DLL.
By doing that the dll will be copied to the root directory of your program and it will the dll.
I think you need to add the full assembly info to the ResourceDictionary Source:
<ResourceDictionary Source="/PresentationFramework.Aero,Version=3.0.0.0,Culture=neutral,PublicKeyToken=31bf3856ad364e35,processorArchitecture=MSIL;component/themes/Aero.NormalColor.xaml" />

How to import one ResourceDictionary into other, in WPF?

Is it possible to add one resource dictionary into other one?
In Dictionary2.xaml define MergedDictionaries (right after the opening ResourceDictionary tag):
<ResourceDictionary.MergedDictionaries>
<ResourceDictionary Source="/Path/to/Dictionary1.xaml" />
</ResourceDictionary.MergedDictionaries>
there's a catch: each time you merge dictionaries you effectively create a copy of the merged dictionary. And it's recursive - if you have Dict3.xaml and Dict4.xaml that both load Dictionary2.xaml, you will have three instances of Dictionary1.xaml created
The solution is a SharedResourceDictionary. The implementation in the tutorial should be seen as a starting point and will probably need some level of tweaking - depending on use scenario. Google "wpf SharedResourceDictionary" for some gotchas and solutions.
From answer to this question by XAMeLi
A snippet straight from a sketchflow project I am working on that shows how to merge resource dictionaries in xaml:
<Application.Resources>
<!-- Resources scoped at the Application level should be defined here. -->
<ResourceDictionary>
<ResourceDictionary.MergedDictionaries>
<ResourceDictionary Source="/Microsoft.Expression.Prototyping.SketchControls;component/ScrollViewerStyles.xaml"/>
<ResourceDictionary Source="/[ProjectABC];component/[fileXYZ].xaml"/>
</ResourceDictionary.MergedDictionaries>
</ResourceDictionary>
</Application.Resources>
This shows merging two additional resource dictionaries into another resource dictionary.
(Note that the order can become important if you have default styles defined in more than one place as they will override each other)
Something like:
ResourceDictionary resources = new ResourceDictionary();
resources.Source = new Uri("/MyModule;component/MyModule.xaml",
UriKind.RelativeOrAbsolute);
Application.Current.Resources.MergedDictionaries.Add(resources);
Might be what you're looking for. We use code like this in our Prism Modules.

In WPF how do I reference a static resource that is defined in a different XAML file?

In WPF how do I reference a static resource that is defined in a different XAML file? It's in the same project.
The other XAML file will need to be a resource dictionary. You merge it into the current file using the MergedDictionaries property of the current ResourceDictionary. See Merged Resource Dictionaries on MSDN. Their example:
<Page.Resources>
<ResourceDictionary>
<ResourceDictionary.MergedDictionaries>
<ResourceDictionary Source="myresourcedictionary.xaml"/>
<ResourceDictionary Source="myresourcedictionary2.xaml"/>
</ResourceDictionary.MergedDictionaries>
</ResourceDictionary>
</Page.Resources>
Then within that Page object you can reference static resources defined in myresourcedictionary.xaml or in myresourcedictionary2.xaml.
"different XAML file" could mean a few different things:
App.xaml: Resources are automatically included in the resource tree of anything that's opened so you don't need to do anything extra.
Window or Page .xaml: Resources can be accessed by any child of an instance of the object like a UserControl that is used in a Window.
ResourceDictionary: Needs to be explicitly merged into the resource tree somewhere above where it is used. This can be App.xaml, Windowxx.xaml, or some lower level element. Use ResourceDictionary.MergedDictionaries to do this.
There are also lots of alternate ways to specify the path but this is the simplest:
<Window>
<Window.Resources>
<ResourceDictionary>
<ResourceDictionary.MergedDictionaries>
<ResourceDictionary Source="Resources/MyResourceDict.xaml" />
</ResourceDictionary.MergedDictionaries>
</ResourceDictionary>
</Window.Resources>

Categories