I have 2 XAML files: MainPage.xaml and Settings.XAML
I'd like to change the MainPage.xaml LayoutRoot.Background property from the Settings.XAML. What is the best way to do this?
Create a ResourceDictionary. Create a new xaml file (e.g. Style.xaml) in your project with these contents
<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:vsm="clr-namespace:System.Windows;assembly=PresentationFramework">
<Color x:Key="MainBackGroundColor">#F6F5E0</Color>
</ResourceDictionary>
Update App.xaml like this. By the way if you want to split your settings into different files you can put each file in this MergedDictionaries section.
<Application x:Class="SonoCine.CineReader.App"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
<Application.Resources>
<ResourceDictionary>
<ResourceDictionary.MergedDictionaries>
<ResourceDictionary Source="Style.xaml" />
</ResourceDictionary.
</ResourceDictionary>
</Application.Resources>
</Application>
Now you should be able to use MainBackGroundColor in your MainPage.xaml like this
Background="{StaticResource MainBackGroundColor}"
Related
I have create a external control library which hosts some resource dictionaries etc. My problem is when I try to apply a style on a window element. Style's changes become visible only in running mode!!!
An example of the resource dictionary from my control library:
<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
<Style x:Key="Window_Style" TargetType="Window">
<Setter Property="Background" Value="#FF272727"/>
</Style>
</ResourceDictionary>
This is how I include my external resource dictionary into my app:
<Application x:Class="SigmaLibMaster.App"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="clr-namespace:SigmaLibMaster"
StartupUri="MainWindow.xaml">
<Application.Resources>
<ResourceDictionary>
<ResourceDictionary.MergedDictionaries>
<ResourceDictionary Source="/SigmaLib;component/Resources/Styles/Window.xaml" />
</ResourceDictionary.MergedDictionaries>
</ResourceDictionary>
</Application.Resources>
</Application>
And how I apply it to my window element:
<Window x:Class="SigmaLibMaster.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:SigmaLibMaster"
mc:Ignorable="d"
Title="MainWindow" Height="480" Width="840"
Style="{DynamicResource Window_Style}">
<Grid >
</Grid>
</Window>
Any idea why is this happening?
PS: Please keep in mind that I recently switched from WinForms to WPF!!! :)
You can sometimes find that resources from libraries don't work at design time.
It's a bug IMO.
The work round I use is design time resources.
This is a mechanism which was originally intended for blend. But the wpf designer in visual studio is the same designer as blend now.
I have a library called uilib.
In the properties of that I add a resource dictionary called DesignTimeResources.xaml. It must be that name.
In the csproj I have the following:
<ItemGroup>
<Page Include="Properties\DesignTimeResources.xaml" Condition="'$(DesignTime)'=='true' OR ('$(SolutionPath)'!='' AND Exists('$(SolutionPath)') AND '$(BuildingInsideVisualStudio)'!='true' AND '$(BuildingInsideExpressionBlend)'!='true')">
<Generator>MSBuild:Compile</Generator>
<SubType>Designer</SubType>
<ContainsDesignTimeResources>true</ContainsDesignTimeResources>
</Page>
Note particularly that ContainsDesignTimeResources tag.
That merges a bunch of resource dictionaries I have in uilib:
<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="clr-namespace:UILib">
<ResourceDictionary.MergedDictionaries>
<ResourceDictionary Source="pack://application:,,,/UILib;component/Resources/Geometries.xaml"/>
<ResourceDictionary Source="pack://application:,,,/UILib;component/Resources/ControlTemplates.xaml"/>
<ResourceDictionary Source="pack://application:,,,/UILib;component/Resources/FontResources.xaml"/>
<ResourceDictionary Source="pack://application:,,,/UILib;component/Resources/UILibResources.xaml"/>
<ResourceDictionary Source="pack://application:,,,/UILib;component/Resources/HypsoColoursRD.xaml"/>
</ResourceDictionary.MergedDictionaries>
</ResourceDictionary>
It will not merge these resources in an extra time when you build. The conditions in the tags mean it's design time only.
You can probably find a bunch more on this by searching now you know it exists.
https://dennymichael.net/2016/07/28/wpf-design-time-resources-dictionary/
I followed this Tutorial and got stuck on the Create Instance of Config Settings Class-part. Here they just add the ObjectDataProvider in the Application.Resources. In my case there is already a ResourceDictionary in this context and I think this causes the problem.
My App.xaml:
<Application x:Class="MyApp.App"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:config="clr-namespace:MyApp.ViewModels"
StartupUri="MainWindow.xaml">
<Application.Resources>
<!-- create instance of config-settings class -->
<ObjectDataProvider x:Key="AppSettingsDataProvider" ObjectType="{x:Type config:AppSettingsManager}"/>
<ResourceDictionary x:Key="MainDictionary">
<!-- also not working: -->
<!--<ObjectDataProvider x:Key="AppSettingsDataProvider" ObjectType="{x:Type config:AppSettingsManager}"/>-->
<ResourceDictionary.MergedDictionaries>
<ResourceDictionary Source="pack://application:,,,/Folder/file1.xaml" />
<ResourceDictionary Source="pack://application:,,,/Folder/file2.xaml" />
<!-- <ResourceDictionary Source="{Binding Source={StaticResource AppSettingsDataProvider}, Path=LoadMethod, Mode=OneWay}"/>-->
</ResourceDictionary.MergedDictionaries>
</ResourceDictionary>
</Application.Resources>
</Application>
When I run the program my ResourceDictionary is not loaded anymore (Application.Current.Ressources.MergedDictionaries is empty), without the ObjectDataProvider everything works fine. Putting the ObjectDataProvider in the ResourceDictionary like suggested in the post Problems adding an ObjectDataProvider in resources did not help (is it different in the Application-class?). So where to put the ObjectDataProvider?
I have defined my resourceDictionary in a separate library as below
<ResourceDictionary
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:cultures="clr-namespace:My_Localization.Cultures"
xmlns:properties="clr-namespace:My_Localization.Properties">
<ObjectDataProvider x:Key="Resources" ObjectType="{x:Type cultures:CultureResources}" MethodName="GetResourceInstance"/>
<ObjectDataProvider x:Key="CultureResourcesDS" ObjectType="{x:Type cultures:CultureResources}"/>
</ResourceDictionary>
I have used this library from another library as below (Header of xaml only)
<msRibbon:RibbonTab x:Class="Ribbon.Planner.PlannerRibbon"
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:msRibbon="clr-namespace:Microsoft.Windows.Controls.Ribbon;assembly=RibbonControlsLibrary"
mc:Ignorable="d"
d:DesignHeight="100" d:DesignWidth="500" Header="{Binding Path=Ribbon_About, Source={StaticResource Resources}}"
>
<Grid>
...
...
...
</Grid>
I have added the reference of My_Localization lib and I am only changing the header. All works fine but the only problem is that in design time I have "Header="{Binding Path=Ribbon_About, Source={StaticResource Resources}}" underlined. When I hover my mouse there is hint "The resource "Resources" could not be resolved"
Why is there an error like hint in my xaml? and then why does it all work fine?
My Solution structure
MainExe - Contains app.xaml. I have merged the resource dictionary here. No problems in xaml since the merge dictionary exists in app.xaml
My_Localization - Lib containing the resource dictionary (code above)
Lib1 - References My_Localization and there are problems in xaml as explained
Lib2 - References My_Localization and there are problems in xaml as explained
Lib3 - References My_Localization and there are problems in xaml as explained
You need to provide a reference to the ResourceDictionary either in the app.xaml file or locally. Resources in app.xaml are available globally to all xaml files of the application.
For Xaml files in library projects the designer works a little differently.
At runtime it will be the app.xaml in the startup project that will be used for all assemblies. At designtime it will be the app.xaml of the local assembly.
This means, you can add a app.xaml file to libraies, which will only be used by the Visual Studio Designer when rendering xaml files from that specific library (Set build action of file to Page).
To reference a ResourceDictionary do this:
<Application xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation">
<Application.Resources>
<ResourceDictionary>
<!-- Other global resources -->
<ResourceDictionary.MergedDictionaries>
<ResourceDictionary Source="pack://application:,,,/ASSEMBLYNAME;component/FOLDERPATH/RDNAME.xaml" />
</ResourceDictionary.MergedDictionaries>
</ResourceDictionary>
</Application.Resources>
</Application>
Where ASSEMBLYNAME is the name of the assembly where the ResourceDictionary is (check properties of project).
Example:
Project with assembly name: "MyAssembly" and ResourceDictionary in folder path "Resources/RDs/MyRd.xaml"
Source="pack://application:,,,/MyAssembly;component/Resources/RDs/MyRd.xaml"
In App.xaml, you must add a MergedDictionary to the resources which will reference your other dictionary.
<Application.Resources>
<ResourceDictionary>
<ResourceDictionary.MergedDictionaries>
<ResourceDictionary Source="pack://application:,,,/RibbonControlsLibrary;component/Your/Dictionary/Path.xaml" />
...
</ResourceDictionary.MergedDictionaries>
</ResourceDictionary>
</Application.Resources>
You can include the ResourceDictionary in each xaml
<msRibbon:RibbonTab x:Class="Ribbon.Planner.PlannerRibbon"
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:msRibbon="clr-namespace:Microsoft.Windows.Controls.Ribbon;assembly=RibbonControlsLibrary"
mc:Ignorable="d"
d:DesignHeight="100" d:DesignWidth="500" Header="{Binding Path=Ribbon_About, Source={StaticResource Resources}}">
<msRibbon:RibbonTab.Resources>
<ResourceDictionary Source="pack://application:,,,/<ASSEMBLY_NAME>;component/<RESOURCES_FILE>.xaml"/>
</msRibbon:RibbonTab.Resources>
<Grid>
...
...
...
</Grid>
I have the following App.xaml:
<Application
x:Class="Genisyss.V2.Client.App"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="clr-namespace:Genisyss.V2.Client"
ShutdownMode="OnExplicitShutdown">
<Application.Resources>
<ResourceDictionary>
<ResourceDictionary.MergedDictionaries>
<ResourceDictionary
Source="Resources/ShellResources.xaml" />
<ResourceDictionary>
<local:AppBootstrapper
x:Key="bootstrapper" />
</ResourceDictionary>
</ResourceDictionary.MergedDictionaries>
</ResourceDictionary>
</Application.Resources>
</Application>
ShellResources.xaml looks like this:
<ResourceDictionary
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:sys="clr-namespace:System;assembly=mscorlib"
x:Class="Genisyss.V2.Client.Resources.ShellResources"
x:ClassModifier="public">
<ResourceDictionary.MergedDictionaries>
<!-- EXTERNAL RESOURCES -->
<ResourceDictionary
Source="/Teton.Wpf;component/Themes/Generic.xaml" />
<ResourceDictionary
Source="Images.xaml" />
</ResourceDictionary.MergedDictionaries>
<!-- controls and templates defined, etc -->
</ResourceDictionary>
Configured this way, the program fails at runtime with "resource not found" or "xaml parse exception".
If I change App.xaml to ALSO include external resources, like this:
<Application
x:Class="Genisyss.V2.Client.App"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="clr-namespace:Genisyss.V2.Client"
ShutdownMode="OnExplicitShutdown">
<Application.Resources>
<ResourceDictionary>
<ResourceDictionary.MergedDictionaries>
<!-- NOTE ADDITION OF EXTERNAL RESOURCES -->
<ResourceDictionary
Source="/Teton.Wpf;component/Themes/Generic.xaml" />
<ResourceDictionary
Source="Resources/ShellResources.xaml" />
<ResourceDictionary>
<local:AppBootstrapper
x:Key="bootstrapper" />
</ResourceDictionary>
</ResourceDictionary.MergedDictionaries>
</ResourceDictionary>
</Application.Resources>
</Application>
Now my program finds the resources at runtime and runs without error. What gives with this? I thought the point of merged resources was ACTUALLY TO MERGE THE RESOURCES, so that you didn't need to declare them in two places.
EDIT
Changed the Source property in ShellResources.xaml to be an absolute pack uri:
pack://application:,,,/Teton.Wpf;component/Themes/Generic.xaml
But this made no difference.
This bug showed up because of the order that things need to be defined in a resource file. I have a WPF controls project that defines some custom controls AND overrides the default styles of several built-in controls.
To make a long story short, I had resources that were defined further down in the Generic.xaml file, and they were being accessed further up - that's a no-no. Resources are apparently parsed only once, in a strict top-down fashion. I was under the impression that they were parsed in a two-or-more pass manner just like normal c# source code.
To avoid this happening, here is a suggested way to lay out your Generic.xaml in a WPF Controls project:
<!-- Shared resources like brushes and colors -->
<!-- DEFAULT control styles, e.g. <Style TargetType="{x:Type TextBox}"... -->
<!-- Control styles for custom controls that are defined in your project -->
Thanks to #Aybe for pushing me to dig deeper on this.
I'm trying to use a WPF Template and I'm supposed to include this in my App.xaml, but I get "Nested properties are not supported: ResourceDictionaries.MergedDictionaries" error and "The attachable property "MergedDictionaries" was not found in type "ResourceDictionary".
<Application x:Class="Unico.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.MergedDictionaries>
<!-- Set default skin -->
<ResourceDictionary Source="\ExpressionDark.xaml"/>
<ResourceDictionary Source="\WindowStyle.xaml"/>
</ResourceDictionary.MergedDictionaries>
<Style TargetType="{x:Type Rectangle}" />
</Application.Resources>
</Application>
I've tried everything but still can't fix this. Any idea? Thanks.
MergedDictionaries is a property of ResourceDictionary.
Change to:
<Application.Resources>
<ResourceDictionary>
<ResourceDictionary.MergedDictionaries>
...
</ResourceDictionary.MergedDictionaries>
<Style TargetType="{x:Type Rectangle}" />
</ResourceDictionary>
</Application.Resources>