Reference external xaml styles from library to WPF Main app - wpf

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>

Related

Xaml designer throws exception when the project code runs behind

When i try to load the view i.e., MainWindow.xaml, unhandled exception occurs. This happens only if the project code is running behind. Otherwise it works fine. Please help.Below are the exception details.
Screenshot here: Screenshot
System.ArgumentNullException
Value cannot be null.
Parameter name: remoteValues
at Microsoft.VisualStudio.DesignTools.DesignerContract.Isolation.Remoting.LocalNotifyingEnumerable2..ctor(IRemoteNotifyingEnumerable1 remoteValues, Func`2 converter)
at Microsoft.VisualStudio.DesignTools.DesignerContract.Isolation.Remoting.LocalDesignerView.Microsoft.VisualStudio.DesignTools.DesignerContract.IDesignerView.get_RelatedDocumentPaths()
at Microsoft.VisualStudio.DesignTools.DesignerContract.IsolatedDesignerService.IsolatedDesignerView.CreateDesignerViewInfo(CancellationToken cancelToken)
I tried clicking on 'click here to disable the project code and reload the designer' . It works when i do this. But when i enable the project code, the same exception comes.
Mainwindow.xaml:
<Window x:Class="QCFilterSaver.View.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"
Style="{DynamicResource MetroStyle}"
xmlns:view="clr-namespace:QCFilterSaver.View"
mc:Ignorable="d"
Title="QC Filter Saver" Height="520" Width="1200" WindowStartupLocation="CenterScreen">
<Window.Resources>
<ResourceDictionary>
<ResourceDictionary.MergedDictionaries>
<ResourceDictionary Source="/Themes/ExpressionDark.xaml"/>
<ResourceDictionary Source="/Themes/MetroDark.MSControls.Core.Implicit.xaml"/>
<ResourceDictionary Source="/Themes/MetroDark.MSControls.Toolkit.Implicit.xaml"/>
<ResourceDictionary Source="/Controls\DataGridStyleDictionary.xaml"/>
<ResourceDictionary Source="/MainDataTemplates.xaml"/>
<ResourceDictionary Source="/Controls/Styles/LoadingArcsRing.xaml"/>
<ResourceDictionary Source="/Controls/Styles/LoadingThreeDots.xaml"/>
</ResourceDictionary.MergedDictionaries>
</ResourceDictionary>
</Window.Resources>
<Grid>
<view:FSView x:Name="FSView" HorizontalContentAlignment="Stretch"/>
</Grid>
</Window>
FSView.xaml:
<UserControl x:Class="QCFilterSaver.View.FSView"
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:local="clr-namespace:QCFilterSaver.ViewModels"
mc:Ignorable="d"
d:DesignHeight="520" d:DesignWidth="1200">
<UserControl.DataContext>
<local:FSViewModel/>
</UserControl.DataContext>
<UserControl.Resources>
<Style TargetType="{x:Type TextBox}">
<Style.Triggers>
<Trigger Property="IsMouseOver" Value="True">
<Setter Property="BorderBrush" Value="#a70711"></Setter>
</Trigger>
</Style.Triggers>
</Style>
</UserControl.Resources>
<Grid>
<!--my properties and bindings here-->
</Grid>
</UserControl>
The designer should load automatically without exception but it just does not.

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.

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>

Is it possible to reference a resource dictionary and define a style in the same resource section?

Like so:
<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">
<Window.Resources>
<ResourceDictionary x:Key=""whatever" Source="colors.xaml" />
<Style TargetType="Button">
<!- button style using colors defined in colors.xaml -->
</Style>
</Window.Resources>
<StackPanel>
<Button Background="{DynamicResource background1}" Height="50"></Button>
<Button Background="{DynamicResource background2}" Height="50"></Button>
</StackPanel>
</Window>
If I do that I get warnings about background1 and background2 not being resolved and an XamlParseException, because the Resource property of window is already defined (it is not). Everything is fine if I remove the stuff.
Any ideas?
It's easy with MergedDictionaries
<Window.Resources>
<ResourceDictionary>
<ResourceDictionary.MergedDictionaries>
<ResourceDictionary x:Key=""whatever" Source="colors.xaml" />
</ResourceDictionary.MergedDictionaries>
<Style TargetType="Button">
<!- button style using colors defined in colors.xaml -->
</Style>
</ResourceDictionary>
</Window.Resources>

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.

Resources