Resource dictionary cannot be found? - wpf

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>

Related

WPF Custom-Control Style Not Implemented

I hope someone can help me please.
I am taking my first tentative steps into WPF by first making a simple custom control. The structure is indicated below.
And the respective code is
MainWindow.xaml
<Window x:Class="WPFCustomControl.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:local="clr-namespace:WPFCustomControl.NewFolder1"
mc:Ignorable="d"
Title="MainWindow" Height="450" Width="800">
<StackPanel Grid.Row="1">
<local:MyCustomControl x:Name = "customControl"
Content = "Click Me" Width = "70"
Margin = "10" Click = "customControl_Click"/>
<TextBlock Name = "txtBlock"
Width = "250" Height = "30"/>
</StackPanel>
Generic.xaml
<ResourceDictionary
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="clr-namespace:WPFCustomControl.NewFolder1">
<Style TargetType="{x:Type local:MyCustomControl}" BasedOn = "{StaticResource {x:Type Button}}">
<Setter Property = "Background" Value = "LightSalmon" />
<Setter Property = "Foreground" Value = "Blue"/>
</Style>
Everything works as expected.
My issue is when I move the Themes folder into the NewFolder1 the application compiles but no Style is implemented.
Thank you in advance for any advice on how to resolve this.
My issue is when I move the Themes folder into the NewFolder1 the application compiles but no Style is implemented.
That's expected. The default style for the control should be located in themes/generic.xaml. This is by convention and where the framework will look for it.
You may move your Style to another ResourceDictionary in NewFolder1 and then modify themes/generic.xaml to merge this one:
<ResourceDictionary
..>
<ResourceDictionary.MergedDictionaries>
<ResourceDictionary Source="pack://application:,,,/WpfCustomControl;component/NewFolder1/YourDictionary.xaml" />
</ResourceDictionary.MergedDictionaries>
Or you could just define your custom Style directly in themes/generic.xaml.
Most probably you are doing following mistake,
go to App.xaml and add Styles as below example
<Application.Resources>
<!-- Resources scoped at the Application level should be defined here. -->
<ResourceDictionary>
<ResourceDictionary.MergedDictionaries>
<ResourceDictionary Source="NewFolder1/Generic.xaml"/>
</ResourceDictionary.MergedDictionaries>
</ResourceDictionary>
</Application.Resources>

Each dictionary entry must have an associated key error message

could someone please help me to solve this problem, I think I have coded right the key required. This is a Style application dictionary test with just one Button. There are two error messages: Each dictionary entry must have an associated key, and All objects added to an IDictionary must have a Key attribute or some other type of key associated with them. Line 13 Position 14, both for MainWIndow.xaml.
There are no more code written by programmer in this project.
This is the MainWindow.xaml code:
<Window x:Class="WpfApplication1.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:local="clr-namespace:WpfApplication1"
mc:Ignorable="d"
Title="MainWindow" Height="350" Width="525">
<Window.Resources>
<ResourceDictionary>
<ResourceDictionary Source="App.xaml" /> This is the offending line
</ResourceDictionary>
</Window.Resources>
<Grid>
<Button Style="{StaticResource algo}" />
</Grid>
And this is the App.xaml code:
<Application x:Class="WpfApplication1.App"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="clr-namespace:WpfApplication1"
StartupUri="MainWindow.xaml">
<Application.Resources>
<Style x:Key="algo" TargetType="{x:Type Button}">
<Setter Property="Background" Value="Red" />
</Style>
</Application.Resources>
As pointed out in the comments, the syntax to reference a ResourceDictionary is
<Window.Resources>
<ResourceDictionary>
<ResourceDictionary.MergedDictionaries>
<ResourceDictionary Source="myresourcedictionary.xaml"/>
</ResourceDictionary.MergedDictionaries>
</ResourceDictionary>
</Window.Resources>
Direct content of ResourceDictionary is considered to be the dictionary's entries. This is where the missing Key error refers to. A dictionary should have look up Keys for all its entries:
<Window.Resources>
<ResourceDictionary>
<conv:BoolToVisibilityConverter x:Key="BoolToVisibilityConverter" />
<conv:BoolToCollapsedConverter x:Key="BoolToCollapsedConverter" />
...
</ResourceDictionary>
</Window.Resources>
An exception to the rule are implicit Styles (Styles that have a TargetType instead of a Key).
In your case none of the above will help, since Resources in App.xaml are treated special. They're considered Global Resources and can be referenced from everywhere. Trying to do reference them explicitly as in the first example will result in
An error occurred while finding the resource dictionary "App.xaml".
Instead change your MainWindow.xaml to
<Window x:Class="WpfApplication1.MainWindow"
...
Title="MainWindow" Height="350" Width="525">
<Grid>
<Button Style="{StaticResource algo}" />
</Grid>
Thank you Funk, thank you Mathew Jibin, your explanations lead me to find what I think is the solution, it is as follows:
Modified App.xaml to be like this:
<Application.Resources>
<Style TargetType="Button">
<Setter Property="Background" Value="Red" />
</Style>
</Application.Resources>
And modified MainWindow deleting everything in Grid:
...
Title="MainWindow" Height="350" Width="525">
<Grid>
</Grid>
Now, everytime I create a new button it has the desired Style. Please let me know if you see any possible problem with this solution. Thanks.

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

ResourceDictionary fails to merge external ResourceDictionaries

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.

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