Unable to reference BrushResource in linked ResourceProject from Style ResourceDictionary - wpf

I have a project in my application where I keep all of my Resources & reusable custom control classes (including styles, brushes, custom controls, etc.).
The App.xaml file of my Application's "Main" project references the ResourceLibrary file that references all my organized ResourceDictionary files like so:
<Application.Resources>
<ResourceDictionary>
<ResourceDictionary.MergedDictionaries>
<ResourceDictionary Source="/ControlResources;component/ResourceDictionaries/ResourceLibrary.xaml"/>
<ResourceDictionary Source="Simple Styles.xaml"/>
</ResourceDictionary.MergedDictionaries>
<Style TargetType="{x:Type Window}">
<Setter Property="FontFamily" Value="Segoe UI" />
</Style>
<Style TargetType="{x:Type Rectangle}" />
</ResourceDictionary>
</Application.Resources>
Note: I am following this article here that includes a big-fix (the Rectangle style included above).
Below is a snapshot of what my "ControlResources" project looks like.
Referencing the style and customControl resources works great when I reference them from my main project, "GlenwareMaster", but when referencing the brush resources under "Brushes" from any of the style resources, the application is clearly not finding them.
My question: Can I just add a project-self-referencing link (an inherent right-click blend feature?). How can I get the style ResourceDictionaries to locate the Brush ResourceDictionaries in the same project?
Thanks in advance!

How are you referencing the brush resource dictionaries in your style dictionaries? Make sure you're using pack URIs and that they are correct.
My standard practice is to use the absolute pack uri format in any resource dictionaries that I plan to reference within another resource dictionary- leads to less errors if you end up moving it to another project in the future. When you reference brushes in your common style resource dictionaries, Try something like:
<ResourceDictionary Source="pack://application:,,,/ControlResources;component/ResourceDictionaries/Brushes/MyBrushes.xaml"/>
You can read more about Pack URIs here: http://msdn.microsoft.com/en-us/library/aa970069.aspx

Related

XAML Restricting visibility of styles from merged ResourceDictionaries

I'm working on a WPF application, which uses styles stored in many resource dictionaries, referenced in App.xaml and I have been struggling with restricting visibility of styles used internally, to build templates of controls.
Let's say that I have a ResourceDictionary called ButtonStyles which contains the following:
<ResourceDictionary.MergedDictionaries>
<ResourceDictionary Source="ButtonInternalStyles.xaml" />
</ResourceDictionary.MergedDictionaries>
<Style TargetType="{x:Type Button}" BasedOn="{StaticResource SomeInternalStyle}">
<!--Setters-->
</Style>
I also have a second ResourceDictionary called ButtonInternalStyles, which contains:
<Style x:Key="SomeInternalStyle" TargetType="{x:Type Button}">
<!--Setters-->
</Style>
My App.xaml references only ButtonStyles ResourceDictionary, but I can use SomeInternalStyle in my Views, which I don't want to be able to do.
Is there a way to restrict a visibility of ButtonInternalStyles, so I can use it only in ButtonStyles?
Is there a way to restrict a visibility of ButtonInternalStyles, so I can use it only in ButtonStyles?
No, I don't think you can do this. All resources defined in a ResourceDictionary that is merged into another ResourceDictionary that is indeed in scope, will also be in scope. That's how resource dictionaries work.
I don't really see the problem though. If you want to prevent a consumer of your ResourceDictionary from accidentally using your "internal" style, you might give it some name that is hard to guess, e.g.:
<Style x:Key="ffdsghdfsgh" TargetType="{x:Type Button}">
...
Of course this won't help if you use some tool for Visual Studio that provides IntelliSense support and I think you're better of not changing the names of your styles. It's not worth the effort.

How to make a globally available style WITHOUT App.xaml

I have a class library I am creating for an AutoCAD plugin that includes WPF control elements. I would like to add a theme to these elements, so I added the WPFThemes.DarkBlend package from Nuget.
To property utilize the theme, you are supposed to add the style reference to your App.xaml file like so:
<Application
...
<Application.Resources>
<ResourceDictionary>
<ResourceDictionary.MergedDictionaries>
<ResourceDictionary Source="Themes\Styles.xaml” />
</ResourceDictionary.MergedDictionaries>
</ResourceDictionary>
</Application.Resources>
Now unfortunately, because this is only a class library, I do not have an App.xaml file in which to add this code. I am able to use my Window.Resources, but in doing so, I am afraid that the styles in the reference are not exposed to the Window element. Is this because the Window is not within the scope of its own resources? Below is an image that shows my current situation:
Thank you!
After creating an x:Key in the style called "DarkWindow", I found that I was able to apply the style directly in the PluginWindow.xaml window properties like this:
<Window Style="{DynamicResource DarkWindow}" />

Global style in a separate assembly

For my application themes, I created a separate class library MyApp.Themes.dll.
In the root folder of this library I have Standard.xaml:
<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
<ResourceDictionary.MergedDictionaries>
<ResourceDictionary
Source="pack://application:,,,/MyApp.Themes;component/Standard/Accordion.xaml"/>
</ResourceDictionary.MergedDictionaries>
</ResourceDictionary>
In Standard folder I have Accordion.xaml:
<ResourceDictionary xmlns:layoutPrimitivesToolkit="..."
xmlns:layoutToolkit="..."
...>
<!-- layoutPrimitivesToolkit:AccordionButton -->
<Style TargetType="layoutPrimitivesToolkit:AccordionButton">
...
</Style>
...
</ResourceDictionary>
which are default styles for WPF Toolkit Accordion control, except that style for
AccordionItem is modified to set background to transparent (instead of blue, which is a known bug).
For both xaml files Build Action is set to "Resource".
Now, after referencing MyApp.Themes library in MyApp WPF project, in App.xaml I wrote the following:
<Application.Resources>
<ResourceDictionary>
<ResourceDictionary.MergedDictionaries>
<ResourceDictionary
Source="pack://application:,,,/MyApp.Themes;component/Standard.xaml" />
</ResourceDictionary.MergedDictionaries>
</ResourceDictionary>
</Application.Resources>
It doesn't work (no error; just style not applied). If I copy&paste Accordion.xaml styles directly in App.xaml, then it works.
Some people suggested adding dummy resource dictionary, so I added the following in App.xaml after MergedDictionaries ending tag:
<Style TargetType="{x:Type layoutToolkit:AccordionItem}" />
Again, it doesn't work. Can someone help me solve this? By the way, I didn't try an approach
suggested by some others - using basedOn. If I must do that, I'd like to do in MyApp.Themes,
because it makes using themes nicer in App.xaml. Thank you in advance.
UPDATE1: It works if I directly copy&paste Accordion.xaml content to Standard.xaml
UPDATE2: I tried local assembly resource file URI (http://msdn.microsoft.com/en-us/library/aa970069.aspx) in Standard.xaml:
<ResourceDictionary Source="pack://application:,,,/Standard/Accordion.xaml"/>
It throws an error, saying standard/accordion.xaml not found.
It seems there's a bug in .NET. See the thread below:
Trouble referencing a Resource Dictionary that contains a Merged Dictionary
Also, there's a connect page on Microsoft site:
https://connect.microsoft.com/VisualStudio/feedback/details/609601/merge-dictionaries-does-not-work-when-we-merge-merged-dictionaries#tabs

WPF Resource access from a different assembly if no App.xaml

I have am creating a WPF extension to an existing Win32 MFC client application. Within a UserControl located in my WPF class library, I am merging libraries as follows:
<ResourceDictionary.MergedDictionaries>
<ResourceDictionary Source="MyResourceDLL;Component/dictionaries/styles.xaml"/>
</ResourceDictionary.MergedDictionaries>
I also tried
<ResourceDictionary.MergedDictionaries>
<ResourceDictionary Source="pack://application:,,,/MyResourceDLL;Component/dictionaries/styles.xaml"/>
</ResourceDictionary.MergedDictionaries>
In either case, I get the following XamlParseException:
System.Windows.Markup.XamlParseException
occurred
Message="MyResourceDLL;Component/dictionaries/styles.xaml'
value cannot be assigned to property
'Source' of object
'System.Windows.ResourceDictionary'.
Cannot locate resource
'ems.wpf.resources;component/dictionaries/styles.xaml'.
Error at object
'System.Windows.ResourceDictionary' in
markup file
'SARMaster.Maryln.EphemerisLib;component/getephemeriscontrol.xaml'
Line 9 Position 37."
I there a way I can load a relative DLL that is not referenced by main project?
I've been looking at the same issue recently. When compiling a Win32 CLR project the dependencies of the assemblies referenced by the MFC project aren't copied, so I simply set up a post-build event to copy the appropriate assemblies to the $(TargetDir).
Not ideal, but I believe it's by design.
I got the same problem and I found the solution. I needed to remove the Style of my ContentPresenter. This line was creating the XamlParseException:
<ContentPresenter.Resources>
<Style TargetType="{x:Type TextBlock}" BasedOn="{StaticResource TextStyle}"/>
</ContentPresenter.Resources>
And after fixing this error, I needed to do these steps to have something 100% working:
Here my projects:
StyleProject: the Class Library project that I want to use. It contains my styles
MainProject: the project that will use the styles
To do so:
Add the reference of my StyleProject inside my MainProject (see here)
Create a ResourceDictionary called MyStyle.xaml inside my MainProject
Add the different dictionaries of my StyleProject following this answer to MyStyle.xaml
Add MyStyle.xaml to the App.xaml using the following code
Code:
<ResourceDictionary Source="Resources/MyStyle.xaml"/>

WPF - Resource not loading from Generic.xaml

Themes\Generic.xaml:
<ResourceDictionary
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
<ResourceDictionary.MergedDictionaries>
<ResourceDictionary Source="WPF Commons;component/Controls/Layout/Foo/FooItem.xaml" />
</ResourceDictionary.MergedDictionaries>
</ResourceDictionary>
Controls\Layout\Foo\FooItem.xaml:
<Style TargetType="{x:Type l:FooItem}">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type l:FooItem}">
<Border>
<ContentPresenter ContentSource="Header" />
</Border>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
If I copy the entire style into my usercontrol resources it works fine. But, if I don't, the usercontrol shows up empty. In Expression Blend 4, I right-clicked and chose Edit Template>, but it won't let me select Edit a Copy... which leads me to believe that something is severely wrong and the Generic.xaml isn't loading properly. I figure it's Generic.xaml because if I remove the MergedDictionary call and copy/paste the xaml style directly into Generic.xaml it still doesn't work.
I'm gonna take a wild guess that you altered your AssemblyInfo.cs file and either changed (or removed) the following line:
[assembly: ThemeInfo(
ResourceDictionaryLocation.None, //where theme specific resource dictionaries are located
//(used if a resource is not found in the page,
// or application resource dictionaries)
ResourceDictionaryLocation.SourceAssembly //where the generic resource dictionary is located
//(used if a resource is not found in the page,
// app, or any theme specific resource dictionaries)
)]
You need to tell your assembly about your ThemeInfo. :)
copying from my blog: http://zoomicon.wordpress.com/2012/06/10/what-to-do-if-generic-xaml-doesnt-get-loaded-for-wpf-control/
at the start of Properties\AssemblyInfo.cs you need (note this isn’t used/needed in Silverlight):
using System.Windows;
...
Mind you that if the project doesn’t show a Properties node in Solution Explorer, you have to either make a new project using the correct template (for a WPF custom control), or right click the project, select Properties, then press the Assembly Information button and enter some dummy values, then OK to create the Properties node (which also creates to a Properties subfolder and AssemblyInfo.cs file).
You can expand (drop-down) the special Properties node in solution explorer then to open AssemblyInfo.cs and add the above stuff if missing

Resources