ResourceDictionary fails to merge external ResourceDictionaries - wpf

I Have a ResourceDictionary Generic.xaml which consists of a set of other resource dictionaries, this is achieved by merging dicionaries. If no resources other than merged dictionaries are defined in my Generic.xaml, during the runtime no styles gets applied.
However if I define any styles in the Gerneric.xaml all starts to work properly.
So the example below doesn't work (this is from my Generic.xaml)
<ResourceDictionary.MergedDictionaries>
<ResourceDictionary Source="pack://application:,,,/Resources;component/ResourceDictionaries/CommonControls/CommonControlsResources.xaml"/>
</ResourceDictionary.MergedDictionaries>
<!--<Style TargetType="{x:Type ToolTip}"/>-->
And here is the working version:
<ResourceDictionary.MergedDictionaries>
<ResourceDictionary Source="pack://application:,,,/Resources;component/ResourceDictionaries/CommonControls/CommonControlsResources.xaml"/>
</ResourceDictionary.MergedDictionaries>
<Style TargetType="{x:Type ToolTip}"/>
Why is that happening?
Edit:
To pin point the problem I have created a sample solution. So the structure of the project is following:
ProjectA WPF Windows Application
ProjectC Class Library, containing styles which are share among all project in the solution folder.
Here is the ProjectA:
<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:,,,/ProjectC;component/Themes/ThemeZ.xaml"/>
</ResourceDictionary.MergedDictionaries>
<!--<Style TargetType="{x:Type ToolTip}"/>-->
</ResourceDictionary>
<Application x:Class="MergedResourceDictionaryIssue.App"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
StartupUri="MainWindow.xaml">
<Application.Resources>
<ResourceDictionary>
<ResourceDictionary.MergedDictionaries>
<ResourceDictionary Source="/Themes/Generic.xaml"/>
</ResourceDictionary.MergedDictionaries>
</ResourceDictionary>
</Application.Resources>
</Application>
<Window x:Class="MergedResourceDictionaryIssue.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="MainWindow" Height="350" Width="525">
<Grid>
<Button/>
</Grid>
</Window>
Here is the ProjectC:
<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
<!-- Styles for all our buttons, let make them all red squares -->
<Style TargetType="{x:Type Button}">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate>
<Grid Width="50"
Height="50"
Background="Red" />
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</ResourceDictionary>
And again if I uncomment the code in the ResourceDictionary project renders as expected, but otherwise the resource dictionary is simply ignored.

According to me, a Dictionary can only contain :
- merged dictionaries
- OR styles
Edit : They are discussing about it here It's a "known" issue and the trick that you used is the currently workaround.

Related

Resource dictionary cannot be found?

At least I think this is the problem...
I have a project structured like so (files omitted for brevity)
Project
Assets
ResourceDictionaries
Styles.xaml
MainWindow.xaml
I am referencing the resource dictionary as follows in MainWindow.xaml
<Window.Resources>
<ResourceDictionary>
<ResourceDictionary.MergedDictionaries>
<ResourceDictionary Source="Assets/ResourceDictionaries/Styles.xaml"/>
</ResourceDictionary.MergedDictionaries>
</ResourceDictionary>
<Window.Resources/>
But none of the styles are being applied to any elements.
I've checked the Build Action is set to page. I've also tried giving some styles in the dictionary a key, but Blend cannot 'see' these keys.
What am I doing wrong?
Edit: Relevant code. Obviously if I put the properties on the actual elements they work, but in a dictionary they don't:
MainWindowStyles.xaml
<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="clr-namespace:Company.Client.Assets.ResourceDictionaries"
xmlns:wpf="http://schemas.syncfusion.com/wpf">
<Style TargetType="{x:Type wpf:RibbonWindow}">
<Setter Property="wpf:SkinStorage.VisualStyle" Value="Office2010Silver"/>
</Style>
<Style TargetType="{x:Type wpf:Ribbon}">
<Setter Property="BackStageColor" Value="#622166"/>
</Style>
</ResourceDictionary>
MainWindow.xaml
<wpf:RibbonWindow x:Class="Company.Client.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:wpf="http://schemas.syncfusion.com/wpf"
xmlns:local="clr-namespace:Company.Client"
mc:Ignorable="d"
Title="MainWindow" Height="600" Width="800">
<wpf:RibbonWindow.Resources>
<ResourceDictionary>
<ResourceDictionary.MergedDictionaries>
<ResourceDictionary Source="Assets/ResourceDictionaries/MainWindowStyles.xaml"/>
</ResourceDictionary.MergedDictionaries>
</ResourceDictionary>
</wpf:RibbonWindow.Resources>
<Grid>
<wpf:Ribbon BackStageHeader="DB">
<wpf:Ribbon.BackStage>
<wpf:Backstage>
<wpf:BackStageCommandButton Header="Save"/>
</wpf:Backstage>
</wpf:Ribbon.BackStage>
</wpf:Ribbon>
</Grid>
</wpf:RibbonWindow>
Edit 2:
This is what has been tried so far:
Tried applying styles to normal controls (Button, Label, etc.). Works
Tried adding the styles under <wpf:MainWindow.Resources>. Doesn't work
Tried a pack URI. Doesn't work
Adding the styles/properties to the actual elements. Works (obviously)
Have you tried these two steps:
Add MainWindowStyles.xaml to Application.Resources section in app.xaml
Use explicit style for RibbonWindow, like this:
<RibbonWindow>
...
<RibbonWindow.Style>
<StaticResource ResourceKey="RadRibbonWindowStyle"/>
<RibbonWindow.Style>
Use the pack URI syntax:
<ResourceDictionary Source="pack://application:,,,/Assets/ResourceDictionaries/Styles.xaml"/>
Adding this to supplement the accepted answer.
My code now looks like this. I didn't manage to get it to work with the VisualStyle property, but this will do. If anyone does know how to get that into a Resource Dictionary though, the help would be much appreciated. :)
Long story short, this is the code that works based on the exchange between me and #AlexSeleznyov
MainWindowStyles.xaml
<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:wpf="http://schemas.syncfusion.com/wpf">
<ResourceDictionary.MergedDictionaries>
<ResourceDictionary Source="/Syncfusion.Tools.Wpf;component/framework/ribbon/themes/office2010silverstyle.xaml"/>
</ResourceDictionary.MergedDictionaries>
<Style x:Key="MainRibbon" TargetType="{x:Type wpf:Ribbon}" BasedOn="{StaticResource Office2010SilverRibbonStyle}">
<Setter Property="BackStageColor" Value="#622166"/>
</Style>
</ResourceDictionary>
MainWindow.xaml
<wpf:RibbonWindow x:Class="Company.Client.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:wpf="http://schemas.syncfusion.com/wpf"
xmlns:local="clr-namespace:Company.Client"
mc:Ignorable="d"
wpf:SkinStorage.VisualStyle="Office2010Silver"
Title="MainWindow" Height="600" Width="800"
Icon="Assets/Icons/ApplicationIcon.ico">
<wpf:RibbonWindow.Resources>
<ResourceDictionary>
<ResourceDictionary.MergedDictionaries>
<ResourceDictionary Source="Assets/ResourceDictionaries/MainWindowStyles.xaml"/>
</ResourceDictionary.MergedDictionaries>
</ResourceDictionary>
</wpf:RibbonWindow.Resources>
<Grid>
<wpf:Ribbon BackStageHeader="File" Style="{StaticResource MainRibbon}">
<wpf:Ribbon.BackStage>
<wpf:Backstage>
<wpf:BackStageCommandButton Header="Save"/>
</wpf:Backstage>
</wpf:Ribbon.BackStage>
</wpf:Ribbon>
</Grid>
</wpf:RibbonWindow>

Reference external xaml styles from library to WPF Main app

I have one Main App.exe WPF on VB.NET. Application have one library C#.NET.
App reference project library.
I try to get style from external library but give error.
This is my "Sharp.LIB" project: "Dictionaries/Buttons.xaml"
<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
<Style TargetType="Button" x:Key="MyButton">
<Setter Property="Background" Value="Green" />
<Setter Property="Width" Value="100" />
<Setter Property="Height" Value="40" />
<Setter Property="Content" Value="Hello from style" />
</Style>
This is my second file "General.xaml" to marge all styles. At now I merge only one Buttons styles.
<ResourceDictionary
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" >
<ResourceDictionary.MergedDictionaries>
<ResourceDictionary Source="Dictionaries/Buttons.xaml" />
</ResourceDictionary.MergedDictionaries>
Here is my usercontrol from Main vb.net app.
<UserControl x:Class="MyWF.UC"
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"
xmlns:ms="clr-namespace:MyStyles;assembly=MyStyles" mc:Ignorable="d"
d:DesignHeight="100" d:DesignWidth="100">
<UserControl.Resources>
<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:,,,/MyStyles;component/General.xaml" />
</ResourceDictionary.MergedDictionaries>
</ResourceDictionary>
</UserControl.Resources>
<Grid>
<Button Style="{StaticResource MyButton}" />
</Grid>
This is my second try. Again failed with the same error according missing file.
<UserControl x:Class="MyWF.UC"
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"
xmlns:ms="clr-namespace:MyStyles;assembly=MyStyles" mc:Ignorable="d"
d:DesignHeight="100" d:DesignWidth="100">
<UserControl.Resources>
<ResourceDictionary
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" >
<ResourceDictionary.MergedDictionaries>
<ResourceDictionary Source="/MyStyles;component/General.xaml" />
</ResourceDictionary.MergedDictionaries>
</ResourceDictionary>
</UserControl.Resources>
<Grid>
<Button Style="{StaticResource MyButton}" />
</Grid>
Error:
Additional information: 'Set property 'System.Windows.ResourceDictionary.Source' threw an exception.' Line number '27' and line position '18'.
{"Cannot locate resource 'general.xaml'."}
PLEASE HELP.
As this question is unsolved till now: The pack URI should look like this:
<ResourceDictionary Source="pack://application:,,,/$assemblyName$;component/$folder$/Style.xaml"/>
see Resource File Pack URIs:
The following example shows the pack URI for a XAML resource file that is located in a subfolder of the referenced assembly's project folder.
pack://application:,,,/ReferencedAssembly;component/Subfolder/ResourceFile.xaml
e.g.
<Window.Resources>
<ResourceDictionary>
<ResourceDictionary.MergedDictionaries>
<ResourceDictionary Source="pack://application:,,,/WPF.Controls;component/Templates/Style.xaml"/>
</ResourceDictionary.MergedDictionaries>
</ResourceDictionary>
</Window.Resources>

When <ResourceDictionary> has both direct resources and merged resources, why can't resources be found?

File app.xaml
<Application.Resources>
<ResourceDictionary>
<SolidColorBrush x:Key="appBrush" Color="Red"/>
<ResourceDictionary.MergedDictionaries>
<ResourceDictionary Source="Dictionary1.xaml"/>
</ResourceDictionary.MergedDictionaries>
</ResourceDictionary>
</Application.Resources>
File Dictionary1.xaml
<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
<ControlTemplate x:Key="ct">
<Rectangle Fill="{StaticResource appBrush }"/>
</ControlTemplate>
</ResourceDictionary>
Then MainWindow uses the template defined.
<Control Template="{StaticResource ct}"/>
Run. It says cannot find appBrush. What's the problem?
Note, changing StaticResource to DynamicResource definitely lets it work. But what is the reason forcing me to make the change?
Change your App.xaml to this and it will work:
<Application.Resources>
<ResourceDictionary>
<ResourceDictionary.MergedDictionaries>
<ResourceDictionary>
<SolidColorBrush x:Key="appBrush" Color="Red"/>
</ResourceDictionary>
<ResourceDictionary Source="Dictionary1.xaml"/>
</ResourceDictionary.MergedDictionaries>
</ResourceDictionary>
</Application.Resources>
I believe it is related to how resources are merged together. In these type of situations, I always use a Brushes.xaml resource dictionary to define all my brushes, and merge that in ahead of any other resource dictionaries.

Xaml Design View can't find Background Brush

in order to clean up my code, I'm trying to split my app.xaml into seperate resource dictionaries. This works at runtime, but not at design time:
snipped in app.xaml
<Application.Resources>
<ResourceDictionary>
<ResourceDictionary.MergedDictionaries>
<ResourceDictionary Source="/;component/Theme/Colors.xaml" />
<ResourceDictionary Source="/;component/Theme/Styles.xaml" />
</ResourceDictionary.MergedDictionaries>
</ResourceDictionary>
</Application.Resources>
Colors.xaml
<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
<SolidColorBrush x:Key="backgroundBrush" Color="Gold"/>
</ResourceDictionary>
Styles.xaml
<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
<Style TargetType="StatusBar">
<Setter Property="Background" Value="{StaticResource backgroundBrush}" />
</Style>
</ResourceDictionary>
Snipped of MainWindow.xaml
<Window x:Class="test.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="test" Width="800" Height="600" >
<StatusBar Name="statusBar" DockPanel.Dock="Bottom">
<StatusBarItem Content="{Binding statusMessage}" />
</StatusBar>
DesignView gives the error:
Error 8 '{DependencyProperty.UnsetValue}' is not a valid value for property 'Background'. C:\Daten\DotNet\test\test\MainWindow.xaml 123
If I put backgroundBrush directly into app.xaml like so:
<Application.Resources>
<ResourceDictionary>
<ResourceDictionary.MergedDictionaries>
<ResourceDictionary Source="/;component/Theme/Colors.xaml" />
<ResourceDictionary Source="/;component/Theme/Styles.xaml" />
<ResourceDictionary>
<SolidColorBrush x:Key="backgroundBrush" Color="Gold"/>
</ResourceDictionary>
</ResourceDictionary.MergedDictionaries>
</ResourceDictionary>
</Application.Resources>
DesignView has no problems.
So is there a way to tell DesignView where to find backgroundBrush, if this brush is placed into a seperate resource dictionary?
Thats the problem with StaticResource isnt it. It needs the resource key resolved explicitly using shared \ merged \ direct resource dictionaries hierarchically up.
There are two options...
merge Colors.xaml dictionary in Styles.xaml
OR
in Styles.xaml refer the bursh using DynamicResource.
In case Resources are in different assemblies than that where MainWindow resides and the one dictionary is refering to the other dictionary. In that case reference is not resolved. This bug is already reported at Microsoft site in case your target framework is 4.0. However they have provided a workaround for it. Simply add the empty style in your Resource dictionaries and it will work fine like this -
<Application.Resources>
<ResourceDictionary>
<ResourceDictionary.MergedDictionaries>
<ResourceDictionary Source="/;component/Theme/Colors.xaml" />
<ResourceDictionary Source="/;component/Theme/Styles.xaml" />
</ResourceDictionary.MergedDictionaries>
<Style TargetType="{x:Type Window}"/>
</ResourceDictionary>
</Application.Resources>
For further refernce please look at this link - https://connect.microsoft.com/VisualStudio/feedback/details/555322/global-wpf-styles-are-not-shown-when-using-2-levels-of-references#details
Try
{StaticResource ApplicationPageBackgroundThemeBrush}
for your status bar background value

Set resource or style to a window from different class library

I am following prism to build wpf application. In my application, there is a helper class library where I defined resources and styles which is going to be used by multiple class libraries in the solution.
But I am getting error when I try to set a resource to Style attribute of a window. The window is in differnt class library as of a resource.
The error that I am getting is :
Cannot find resource named '{resourceName}'. Resource names are case sensitive. Error at object 'MyWindow' in markup file
I used the following code but it is not working
<Window x:Class="Class1" Style="{StaticResource resourceName}">
<Window.Resources>
<ResourceDictionary>
<ResourceDictionary.MergedDictionaries>
<ResourceDictionary Source="pack://application:,,,/classlibrary;component/Dictionary/resource1.xaml" /> </ResourceDictionary.MergedDictionaries>
< /ResourceDictionary>
< /Window.Resources>
</Window>
You need to use the DynamicResource markup extension. The reason for this is because the external ResourceDictionary you import is declared in your xaml after the style is set for your Window. A working example of setting a Window's style with a style defined in a referenced class library is below:
The "MainWindow" xaml:
<Window x:Class="WpfApplication3.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="MainWindow" Height="350" Width="525"
Style="{DynamicResource TestStyle}">
<Window.Resources>
<ResourceDictionary>
<ResourceDictionary.MergedDictionaries>
<ResourceDictionary
Source="pack://application:,,,/ClassLibrary1;component/Styles.xaml">
</ResourceDictionary>
</ResourceDictionary.MergedDictionaries>
</ResourceDictionary>
</Window.Resources>
<Grid>
</Grid>
</Window>
The ResourceDictionary (defined in a file named Styles.xaml) in a class library:
<ResourceDictionary
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
<Style x:Key="TestStyle" TargetType="Window">
<Setter Property="Background">
<Setter.Value>
<SolidColorBrush Color="Green"></SolidColorBrush>
</Setter.Value>
</Setter>
</Style>
</ResourceDictionary>
You can use a pack URL to get a resource dictionary from another assembly. Check this thread.
Here is an example of a resource dictionary read from a Common assembly:
<Application.Resources>
<ResourceDictionary>
<ResourceDictionary.MergedDictionaries>
<ResourceDictionary Source="pack://application:,,,/Common;component/styles.xaml"/>
</ResourceDictionary.MergedDictionaries>
</ResourceDictionary>
</Application.Resources>

Resources