DynamicResource Cannot be resolved - wpf

I have been trying to learn about resources and styles, I want to create a chromeless window.
I have an example that acheives what I want via the following simple extracts of xaml.
I have a Resource set in Themes/Generic.xaml
<Style x:Key="BorderlessWindowStyle" TargetType="{x:Type Window}">
<Setter Property="AllowsTransparency" Value="true" />
<Setter Property="WindowStyle" Value="None" />
<Setter Property="ResizeMode" Value="CanResizeWithGrip" />
<Setter Property="Background" Value="Transparent" />
</Style>
I have a main window:
<Window x:Class="Project1.Shell"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="clr-namespace:Project1"
x:Name="Window"
Title="Shell" Height="576" Width="1024" Style="{DynamicResource BorderlessWindowStyle}">
<Grid></Grid>
But the style is not being applied and VS designer states it cannot resolve the resource.
The example I have been looking at does things this way and I cannot discover the difference between what I have seen done and what I am trying to do.
I thought that Genric.xaml was a 'special' resource dictionary that should be discoverable by my Window control - and I am guessing this assumption is my error.
What do I need to do to make this work? (Now I understand I can set these properties in the Window xaml directly, and I have done so and get the effect I want. BUT I really want to undersatnd using the Generic.xaml resource dictionary way as I have presented here)
best regards
John.

Themes/generic.xaml file is automatically used to find default styles for Custom Controls. In your case you have an ordinary Window with custom style. You cannot define this style in Window.Resources section, because the style should be defined at a higher level. The only higher level of Window is App.xaml, because the Window is in fact its child. That's why the solution for your question is to place the style into App.Resources section.

Thought I would add the following example in case it helps some others out. To add a resource dictionary to your app.xaml file you can add the following xaml code to the app.xaml file.
<Application x:Class="ProjectX.App"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="clr-namespace:ProjectX"
StartupUri="MainWindow.xaml">
<Application.Resources>
<ResourceDictionary>
<ResourceDictionary.MergedDictionaries>
<!-- Use the Black skin by default -->
<ResourceDictionary Source="Resources\ResourceFile.xaml"/>
</ResourceDictionary.MergedDictionaries>
</ResourceDictionary>
</Application.Resources>
Where 'Resources' coudl be a folder in your project that contains the Resource Dictionary file (ResourceFile.xaml).
The you can add code to your resource dictionary like such:
<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="clr-namespace:ProjectX.Resources">
<!-- The Background Brush is used as the background for the Main Window -->
<SolidColorBrush x:Key="MainBackgroundBrush" Color="#FF202020" />
</ResourceDictionary>
And then finally, dynamically bind to your resource dictionary doing something like:
<Window
x:Class="ProjectX.MainWindow"
Title="Family.Show" Height="728" Width="960"
Background="{DynamicResource MainBackgroundBrush}"
ResizeMode="CanResizeWithGrip">
</Window>

Related

xaml ResourceDictionary inside User Control Library

how is it possible to define a ResourceDictionary inside a User Control Library and access them via Xaml-Code.
I've created something like this:
<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:Controls="clr-namespace:MahApps.Metro.Controls;assembly=MahApps.Metro"
xmlns:Dialog="clr-namespace:MahApps.Metro.Controls.Dialogs;assembly=MahApps.Metro"
>
<Style x:Key="NormalStyle" TargetType="{x:Type Control}">
<Setter Property="Foreground" Value="Black" />
<Setter Property="FontSize" Value="12" />
<Setter Property="FontFamily" Value="Arial" />
<Setter Property="FontStyle" Value="Normal" />
</Style>
.
.
.
</ResourceDictionary
And now I want to use this "NormalStyle" with a Control
Style="{StaticResource NormalStyle}"
But Visual Studio says "The resource "NormalStyle" could not be resolved."
Did i miss or forget something?
Thanks for helping me
You will have to include or merge your ResourceDictionary with UserControl.Resources like below. Here in Source give path to your ResourceDictionary.
<UserControl.Resources>
<ResourceDictionary Source="MyResourceDictionary.xaml"/>
</UserControl.Resources>
OR
<UserControl.Resources>
<ResourceDictionary>
<ResourceDictionary.MergedDictionaries>
<ResourceDictionary Source="MyResourceDictionary.xaml"/>
</ResourceDictionary.MergedDictionaries>
</ResourceDictionary>
</UserControl.Resources>
Then you can use the resources in the dictionary inside your UserControl
Style="{StaticResource NormalStyle}"
Please add style reference in App.xamal therfore so that it loads when you run the application.
When you add any external resource file you need to add it in App.xamal to get it's reference in your app else you need to manually add reference to every xamal form to access style and templates
This is how you going to add it in App.xamal using MergedDictionaries than where ever you refer any style in you application it will have it's reference
<ResourceDictionary.MergedDictionaries>
<!--
Styles that define common aspects of the platform look and feel
Required by Visual Studio project and item templates
-->
<ResourceDictionary Source="Common/CommonStyles.xaml"/>
<ResourceDictionary Source="Project/Common/CommonStyles.xaml"/>
</ResourceDictionary.MergedDictionaries>
Hope that helps
Alright, so I got it half to work. Inside my UserControlLibrary i made a new Xaml-File "UIStandards", where put all my Styles into. Now in my Main Project, i want to have access to these Styles and I think i should use a MergedDictionary.
What i did was this:
<Application x:Class="MentorPlusClientWindowsWPF.App"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="clr-namespace:MentorPlusClientWindowsWPF"
xmlns:Controls="clr-namespace:MahApps.Metro.Controls;assembly=MahApps.Metro"
xmlns:Dialog="clr-namespace:MahApps.Metro.Controls.Dialogs;assembly=MahApps.Metro"
Startup="Application_Startup">
<!--StartupUri="MainWindow.xaml"-->
<Application.Resources>
<ResourceDictionary>
<ResourceDictionary.MergedDictionaries>
<ResourceDictionary Source="pack://application:,,,/CrossProjectUserControls;component/UIStandards.xaml" />
</ResourceDictionary.MergedDictionaries>
</ResourceDictionary>
</Application.Resources>
As you can see, i referenced the UISTandards.xaml but inside a UserControl inside my MainProject, none of my Styles can be found.
Any solutions?

Defining WPF Window style in class library

Currently I am developing some WPF class library, which will have several WPF Windows and trying to create my own window ControlTemplate for these Windows to make more nice design of these windows (inspired by this article: Reusing Control Templates in Resource Dictionaries).
Problem is, then it's a WPF class library not an application assembly, where i can use app.xaml and to define my resource dictionary reference & etc...
Using code below i getting an error: StaticResource reference 'MyWindowStyle' was not found
<Window x:Class="SomeERP.Window1"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="Window1" Height="300" Width="300"
Style="{StaticResource MyWindowStyle}">
<Window.Resources>
<!-- My Window Style -->
<Style x:Key="MyWindowStyle" TargetType="Window">
<Setter Property="Background" Value="Transparent" />
<Setter Property="WindowStyle" Value="None" />
<Setter Property="AllowsTransparency" Value="True" />
<Setter Property="Opacity" Value="0.95" />
<Setter Property="Template" Value="{StaticResource MyWindowTemplate}" />
</Style>
<!-- Window Template -->
<ControlTemplate x:Key="MyWindowTemplate" TargetType="{x:Type Window}">
<Grid>
</Grid>
</ControlTemplate>
</Window.Resources>
</Window>
I suspect i get this error because in my case it's not predeclared before Window declaration as in application's case in app.xaml which i don't have in class libary. I am pretty new in WPF and just starting to use WPF design possibilities.
If you need the style only once, the solution is pretty simple: Just define the style in-place
<Window.Style>
<!-- My Window Style -->
<Style TargetType="Window">
...
</Style>
</Window.Style>
However, if you need the style in more than one window, it is reasonable to define the style in a resource dictionary. Then you can integrate the resource dictionary in the window's resources and set the style accordingly:
<Window.Resources>
<!-- My Window Style -->
<ResourceDictionary>
<ResourceDictionary.MergedDictionaries>
<ResourceDictionary Source="Dictionary1.xaml"/>
<!-- path to the resource dictionary -->
</ResourceDictionary.MergedDictionaries>
</ResourceDictionary>
</Window.Resource>
<Window.Style>
<StaticResource ResourceKey="MyWindowStyle"/>
</Window.Style>
Looks like i've found solution to my problem in this post: Assembly-wide / root-level styles in WPF class library and according to this post What's the difference between StaticResource and DynamicResource in WPF?
A StaticResource will be resolved and assigned to the property during the loading of the XAML which occurs before the application is actually run. It will only be assigned once and any changes to resource dictionary ignored.
A DynamicResource assigns an Expression object to the property during loading but does not actually lookup the resource until runtime when the Expression object is asked for the value. This defers looking up the resource until it is needed at runtime. A good example would be a forward reference to a resource defined later on in the XAML. Another example is a resource that will not even exist until runtime. It will update the target if the source resource dictionary is changed.
That was what i needed, as i have class library, i don't have app.xaml and can't predeclare resources for Window. I just need to use DynamicResource rather than StaticResource to get it working.
Thanks for attention :)
Just add the external assembly:
<Application.Resources>
<ResourceDictionary>
Source="/MyAssemblyName;component/MyResources.xaml"
</ResourceDictionary>
</Application.Resources>

How should application wide resources be organized?

Here is the scenario:
I have been using VS 2010 to write quite a large WPF project using MEF. There are multiple projects within this solution and I have one ResourceDictionary for all of my styles.
The AppStyles.xaml ResourceDictionary is located in my startup project, it contains all of my styles for the project. And within my App.xaml I have the following:
<Application x:Class="Dionysus.Shell.App"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
DispatcherUnhandledException="UnhandledException" ShutdownMode="OnMainWindowClose">
<Application.Resources>
<ResourceDictionary>
<ResourceDictionary.MergedDictionaries>
<ResourceDictionary Source="AppStyles.xaml"/>
</ResourceDictionary>
</Application.Resources>
Now, this all works perfectly in design mode of VS 2010 and when I am debugging, the correct styles are being applied to all of my controls. But I recently switched to VS 2012, and the designer is no longer working! When I debug it works perfectly but whenever I use one of my styles as follows:
<Button Name="btnForward" Height="23" Margin="10,0" Style="{StaticResource DionysusButton}" Grid.Row="2" Grid.Column="0"/>
I get the following error in the VS 2012 designer:
The resource "DionysusButton" could not be resolved.
I am clueless as to why this is happening, I have renamed my Style, and even the ResourceDictionary to no avail.
Is there a different way I should be doing this in VS 2012 or is this a problem with VS 2012?
I have found a lot of posts that say that changing the x:Name property of my AppStyles.xaml ResourceDictionary to x:Key will resolve this problem but I cannot do that as it is not a valid option for a ResourceDictionary.
Thanx in advance
-- UPDATE
I am using Marc's answer and all seems to be going well except for default styles. I have the following style:
<Style TargetType="DataGrid" x:Name="DataGridStyle"/>
And this is my main ResourceDictionary:
<ResourceDictionary x:Name="Main"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
<ResourceDictionary.MergedDictionaries>
<ResourceDictionary Source="Styles/AppStyling.xaml" />
</ResourceDictionary.MergedDictionaries>
<Style TargetType="DataGrid" BasedOn="{StaticResource DataGridStyle}"/>
When I do not add the Style tag in my main ResourceDictionary it works fine, but the style is not being applied to all items obviously. When I do add it, i get the following exception:
Provide value on 'System.Windows.Markup.StaticResourceHolder' threw an exception
Ideas?
Are you trying to use the styles which are located in your app.xaml in your modules which you export into the shell using PRISM? The modules should not have a reference to your application/shell project (the startup project)? Then they maybe just don't 'know' the project, which contains the styles? Though the question is why it works in VS2010 then... Please let me know, if I misunderstood your MEF scenario, I'll adapt my answer then.
Resources and Prism is abit tricky, and I am a fan of the following approach, which I have posted before, but it might help in your case too. It is much more appropriate for a PRISM solution than placing your resources inside app.xaml:
I usually create a seperate styling project, which I reference from the projects, which I want to style. The styling project has a fixed structure like this:
For every control, I create a styling ResourceDictionary. For example for my buttons:
<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
<Style x:Key="PrimaryButtonStyle" TargetType="Button">
</Style>
<Style x:Key="ToolbarButton" TargetType="Button">
<Setter Property="BorderThickness" Value="0" />
<Setter Property="Margin" Value="3"/>
<Setter Property="Background" Value="Transparent"></Setter>
</Style>
</ResourceDictionary>
In one main ResourceDictionary, I merge all the other dictionaries, in this case in the file IncaDesign.xaml, which you can see in the picture above:
<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:controls="clr-namespace:Commons.Controls;assembly=Commons">
<ResourceDictionary.MergedDictionaries>
<ResourceDictionary Source="Converter/Converter.xaml" />
<ResourceDictionary Source="Styles/Button.xaml" />
<ResourceDictionary Source="BitmapGraphics/Icons.xaml" />
</ResourceDictionary.MergedDictionaries>
<!-- Default Styles -->
<Style TargetType="Button" BasedOn="{StaticResource PrimaryButtonStyle}"></Style>
</ResourceDictionary>
Notice how I defined the default styles, which are applied automatically, unless you specify otherwise. In every window or control, that you want to style, you only need to reference this one ResourceDictionary. Note the definition of the source, which is a reference to the assembly (/Commons.Styling;component...)
<UserControl.Resources>
<ResourceDictionary>
<ResourceDictionary.MergedDictionaries>
<ResourceDictionary Source="/Commons.Styling;component/IncaDesign.xaml" />
</ResourceDictionary.MergedDictionaries>
<!-- Here you can added resources which belong to the UserControl only -->
<!-- For example: -->
<DataTemplate x:Kex="UcTemplate" />
</ResourceDictionary>
</UserControl.Resources>
Default styles will be set automatically now, and if you want to access a resource explicitly, you can do this, using StaticResource.
<Viewbox Height="16" Width="16" Margin="0,0,10,0">
<ContentControl Content="{StaticResource FileIcon32}" />
</Viewbox>
This is very nice solution in my opinion, which works for very complex solutions, including modular solutions, for example built with PRISM.

Apply themes to wpf and use styles

I am trying to apply a theme to a bunch of wpf projects. There is one assembly containing the generic.xaml and different applications. As far as i understand i can't use the ThemeInfo attribute with ResourceDictionaryLocation.ExternalLocation because the name have to be the same as my program but I have more than one program...
So I search and found that I only have to include the dictionary as MergedDictionary in the app.xaml
<Application.Resources>
<ResourceDictionary>
<ResourceDictionary.MergedDictionaries>
<ResourceDictionary Source="/ClassLibrary1;component/Themes/generic.xaml" />
</ResourceDictionary.MergedDictionaries>
</ResourceDictionary>
</Application.Resources>
This basically works. But if I use a style for the controls it will not apply the generic.xaml style anymore:
generic.xaml in ClassLibrary1.dll
<ResourceDictionary x:Class="ClassLibrary1.Themes.generic"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
<Style TargetType="{x:Type Button}">
<Setter Property="Background"
Value="Black" />
</Style>
Window in program
<Window x:Class="Theming.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">
<Window.Resources>
<Style TargetType="Button"
x:Key="ButtonGreenTextStyle">
<Setter Property="Foreground"
Value="Green" />
</Style>
</Window.Resources>
<Grid>
<Button Style="{DynamicResource ButtonGreenTextStyle}" Content="Test" />
</Grid>
</Window>
What I have to do, that WPF will understand the style in my generic.xaml as basestyle for all buttons (I know I will also have to write a ControlTemplate; the above code is just for simplicity)
Two things I would try
Create a generic ButtonBase style/template to set the look of all
buttons
Try using a BasedOn attribute on the ButtonGreeTextStyle,
basing it on an existing style.
I found another solution. You have to write styles based on a custom markup:
This will apply the current theme style. The code for this MarkupExtension can be found here:
How do I alter the default style of a button without WPF reverting from Aero to Classic?

DataTemplates in resource dictionaries don't inherit from app.xaml styles?

I added custom named styles to the app.xaml.
I created an external resource dictionary (which I attach in the merged dictionaries of the app.xaml) and when I try to use one of the above named styles in the rcource dictionary, it says that there is no such style.
Also the default styles (i.e. unnamed styles that apply for the entire application) don't apply on the template elements.
Note: The Build Action of the templates is 'Page'.
Here is an example of how my code is written:
<Application x:Class="Application"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
ShutdownMode="OnExplicitShutdown">
<Application.Resources>
<ResourceDictionary>
<Style
x:Key="StackPanelStyle"
TargetType="StackPanel"
BasedOn="{StaticResource {x:Type StackPanel}}">
<Setter Property="Margin" Value="5"/>
<Setter Property="Orientation" Value="Horizontal" />
<Setter Property="Height" Value="40"/>
</Style>
<ResourceDictionary.MergedDictionaries>
<ResourceDictionary Source="/Templates/DataTemplate1.xaml"/>
<ResourceDictionary Source="/Templates/DataTemplate2.xaml"/>
<ResourceDictionary Source="/Templates/DataTemplate3.xaml"/>
</ResourceDictionary.MergedDictionaries>
</ResourceDictionary>
</Application.Resources>
</Application>
This an example of the data template:
<DataTemplate DataType="{x:Type Entity}" x:Key="NameDataTemplate">
<Expander>
<StackPanel>
<--The following line produces: StackPanelStyle was not found.-->
<StackPanel Style="{StaticResource StackPanelStyle}">
<Label Content="Name:"/>
<TextBox Text="{Binding Name}"/>
</StackPanel>
</StackPanel>
</Expander>
</DataTemplate>
Any ideas?
Do I have to merge the dictionaries in a different way?
The code won't work well because the DataTemplate in the resource dictionary doesn't know which one is using it, it just been used. Like Hollywood mode. They compiled separately.
To make this work, you can put your style which in app.xaml in the same resource dictionary of the DataTemplate or if you don't like this coupling, you can put it in a different resource dictionary, and merge it into the DataTemplate's resource dictionary.
The Build Action for your App.xaml should be ApplicationDefinition, and the build action for your Resource Dictionary files should be Page. I'm guessing you have both of those correct because they are default (and I see that you mentioned about Page already).
I can't think of any other problem with your situation. As long as your static resources are defined in the correct order, which they appear to be, it should be able to find them when you run your application.
Edit
Debugging idea: Create a fresh resource dictionary called "TestDictionary.xaml" with a simple button style. Make sure this dictionary is in the same folder as your other dictionaries (DataTemplate1.xaml, etc.). Put a link to only TestDictionary in MergedDictionaries (comment out the others). Put a button on your startup window and apply the style. See if just that works. If it fails, you know you have an issue with your merge. If it succeeds, something about your DataTemplate might be the problem.

Resources