access ResourceDictionary across different projects in solution - c#

How do I access a ResourceDictionary from different project in a solution?
My Solution file contains a few projects. One of these projects is named "Common" and contains a Resource called SharedResource.xaml.
SharedResource.xaml in Common:
<ResourceDictionary 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"
mc:Ignorable="d">
<ImageBrush x:Key="UserIcon" ImageSource="/Images\icon_user.png"/>
</ResourceDictionary>
This is how I tried to make the SharedResource Dictionary usable in one of my UserControls.
<UserControl x:Class="MasterDataManagement.View.DisplayMasterDataView"
xmlns:telerik="http://schemas.telerik.com/2008/xaml/presentation"
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:i="http://schemas.microsoft.com/expression/2010/interactivity"
xmlns:command="http://www.galasoft.ch/mvvmlight"
xmlns:common="clr-namespace:Common;assembly=Common"
mc:Ignorable="d"
d:DesignWidth="800" d:DesignHeight="600" d:DataContext="{Binding DisplayMasterDataViewModel, Source={StaticResource ViewModelLocator}}">
<UserControl.Resources>
<ResourceDictionary> <!-- ERROR Each dictionary entry must have an associated key.-->
<ResourceDictionary.MergedDictionaries>
<ResourceDictionary Source="pack://application:,,,/Common;component/Resources/SharedResources.xaml"/>
</ResourceDictionary.MergedDictionaries>
</ResourceDictionary>
</UserControl.Resources>
<Grid>
<!-- Removed Content -->
</Grid>
</UserControl>
Unfortunately, this approach doesn't work and I'm not sure what I missed. The Code above causes this error message: Each dictionary entry must have an associated key.
Any thoughts?
Notes:
I can't put the ResourceDictionary into App.xaml because I create direct UserControl instances(something like UserControl uc = new DisplayMasterDataView() ).
Only the App.xaml from the Project which is set as StartUp Project is "executed". My solution consists out of one MainProject (which is set as StartUp Project) and a few other projects which are used as modules in the MainProject. Now, I need to use this modules in my MainProject which is done like this:
UserControl uc = new DisplayMasterDataView();
My point is that creating an instance of an UserControl from a different project does not execute the App.xaml in the project which consist the UserControl. Therefore I have to use <UserControl.Resources> </UserControl.Resources> to define my resources.
I just mentioned this because the most sample projects use the App.xaml to define Resources.

Each dictionary entry must have an associated key...
Surely that error is just telling you that you need to add a key to your ResourceDictionary using the x:Key notation... in this case, the 'dictionary entry' is your ResourceDictionary and the 'associated key' is whatever you call it to reference it later, in my example below, 'CommonResourceDictionary':
<ResourceDictionary x:Key="CommonResourceDictionary">
<ResourceDictionary.MergedDictionaries>
<ResourceDictionary
Source="pack://application:,,,/Common;component/Resources/SharedResources.xaml"/>
</ResourceDictionary.MergedDictionaries>
</ResourceDictionary>

My WinView project contains a file called ViewResources.xaml in which I place all the resources needed by the controls in that project. It also links in other xaml files in the same project:
<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
<ResourceDictionary.MergedDictionaries>
<ResourceDictionary Source="MainTabControlStyle.xaml" />
</ResourceDictionary.MergedDictionaries>
<!-- ==================== Data Templates ==================== -->
<DataTemplate DataType="{x:Type myNameSpace:MyViewModel}">
<controls:MyUserControl MyProperty="{Binding ...etc...}" />
</DataTemplate>
</ResourceDictionary>
My main project then references this in App.xaml:
<ResourceDictionary>
<ResourceDictionary.MergedDictionaries>
<!-- Main Theme -->
<ResourceDictionary Source="pack://application:,,,/WPF.Themes;component/BureauBlue/Theme.xaml" />
<!-- Global Resources for Views -->
<ResourceDictionary Source="pack://application:,,,/MyProject.WinView;component/ViewResources.xaml" />
<ResourceDictionary Source="pack://application:,,,/MyProject.WinUI;component/HelpResources.xaml" />
... and so on and so forth ...
</ResourceDictionary.MergedDictionaries>
</ResourceDictionary>
</Application.Resources>
I don't see how this would stop you from creating UserControls directly.

Here comes the solution, thanks you for pointing me into the right direction Rohit Vats!
Not Working
<UserControl.Resources>
<gridView:RadContextMenuXamlHolder x:Key="ContextMenuHolder">
<telerik:RadContextMenu DataContext="{Binding Path=UIElement.Column.DataControl.DataContext, RelativeSource={RelativeSource Self}}" InheritDataContext="False"
StaysOpen="True" x:Name="CellCellContextMenu" Placement="Bottom" Loaded="ContextMenu_OnLoaded">
<telerik:RadMenuItem x:Name="ColumnsMenuEntry" Header="Choose Columns:" ItemsSource="{Binding Path=Menu.UIElement.Column.DataControl.Columns, RelativeSource={RelativeSource Self}}" StaysOpenOnClick="True">
<telerik:RadMenuItem.ItemContainerStyle>
<Style TargetType="telerik:RadMenuItem">
<Setter Property="Header" Value="{Binding Header}" />
<Setter Property="IsChecked" Value="{Binding IsVisible, Mode=TwoWay}" />
<Setter Property="IsCheckable" Value="True" />
</Style>
</telerik:RadMenuItem.ItemContainerStyle>
</telerik:RadMenuItem>
<telerik:RadMenuItem Header="Show all columns" Click="RadMenuItem_ShowAllColumns_OnClick"/>
<telerik:RadMenuItem Header="Hide all columns" Click="RadMenuItem_HideAllColumns_OnClick"/>
</telerik:RadContextMenu>
</gridView:RadContextMenuXamlHolder>
<Style TargetType="telerik:GridViewHeaderCell">
<Setter Property="telerik:RadContextMenu.ContextMenu" Value="{Binding Path=CellContextMenu, Source={StaticResource ContextMenuHolder}}"/>
</Style>
<ResourceDictionary>
<ResourceDictionary.MergedDictionaries>
<ResourceDictionary Source="pack://application:,,,/Common;component/SharedResources.xaml"/>
</ResourceDictionary.MergedDictionaries>
</ResourceDictionary>
</UserControl.Resources>
Working
<UserControl.Resources>
<ResourceDictionary>
<gridView:RadContextMenuXamlHolder x:Key="ContextMenuHolder">
<telerik:RadContextMenu DataContext="{Binding Path=UIElement.Column.DataControl.DataContext, RelativeSource={RelativeSource Self}}" InheritDataContext="False"
StaysOpen="True" x:Name="CellCellContextMenu" Placement="Bottom" Loaded="ContextMenu_OnLoaded">
<telerik:RadMenuItem x:Name="ColumnsMenuEntry" Header="Choose Columns:" ItemsSource="{Binding Path=Menu.UIElement.Column.DataControl.Columns, RelativeSource={RelativeSource Self}}" StaysOpenOnClick="True">
<telerik:RadMenuItem.ItemContainerStyle>
<Style TargetType="telerik:RadMenuItem">
<Setter Property="Header" Value="{Binding Header}" />
<Setter Property="IsChecked" Value="{Binding IsVisible, Mode=TwoWay}" />
<Setter Property="IsCheckable" Value="True" />
</Style>
</telerik:RadMenuItem.ItemContainerStyle>
</telerik:RadMenuItem>
<telerik:RadMenuItem Header="Show all columns" Click="RadMenuItem_ShowAllColumns_OnClick"/>
<telerik:RadMenuItem Header="Hide all columns" Click="RadMenuItem_HideAllColumns_OnClick"/>
</telerik:RadContextMenu>
</gridView:RadContextMenuXamlHolder>
<Style TargetType="telerik:GridViewHeaderCell">
<Setter Property="telerik:RadContextMenu.ContextMenu" Value="{Binding Path=CellContextMenu, Source={StaticResource ContextMenuHolder}}"/>
</Style>
<ResourceDictionary.MergedDictionaries>
<ResourceDictionary Source="pack://application:,,,/Common;component/SharedResources.xaml"/>
</ResourceDictionary.MergedDictionaries>
</ResourceDictionary>
</UserControl.Resources>
the trick was to move all resources into the <ResourceDictionary> </ResourceDictionary> tag.

Related

ResourceDictionary is not used as button style

I am trying to use ResourceDictionary to set up a style for a button
<Window.Resources>
<vieModel:MainWindowViewModel x:Key="MainViewModel"/>
<ResourceDictionary x:Key="ButtonStyle"> //If I don't use key it gives error
<ResourceDictionary.MergedDictionaries>
<ResourceDictionary Source="GlassButton.xaml"/>
</ResourceDictionary.MergedDictionaries>
</ResourceDictionary>
</Window.Resources>
and using it as
<Button Style="{DynamicResource ButtonStyle}"/>
Now, when I do this it complains that ResourceDictionary can not be applied to Style. When I use "GlassButton" as defined in GlassButton.xaml it says that GlassButton could not be resolved.
when I use it like
<Button Style="{StaticResource ButtonStyle}"/>
or use GlassButton in both cases either it complains or wont work.
GlassButton.xaml looks like this, and compiling fine
<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="clr-namespace:Citations">
<Style x:Key="GlassButton" TargetType="{x:Type Button}">
<Setter Property="FontSize" Value="42" />
<Setter Property="Foreground" Value="White" />
<Setter Property="Template">
I am taking this example from here or here both are kind of using same approach of using ResourceDictionary. I am doing as shown but it still not working. Do I need a converter for this? or I am doing something wrong?
The following worked for me. Check that the path to GlassButton.xaml is correct. If you put it in a folder such as Styles you would need to use Source="Styles/GlassButton.xaml".
<Window.Resources>
<ResourceDictionary>
<ResourceDictionary.MergedDictionaries>
<ResourceDictionary Source="GlassButton.xaml"/>
</ResourceDictionary.MergedDictionaries>
</ResourceDictionary>
</Window.Resources>
<Grid>
<Button Style="{DynamicResource GlassButton}"
Content="Button Content"/>
</Grid>
I should be using it as follows
<Window.Resources>
<ResourceDictionary>
<ResourceDictionary.MergedDictionaries>
<ResourceDictionary Source="GlassButton.xaml"/>
</ResourceDictionary.MergedDictionaries>
<vieModel:MainWindowViewModel x:Key="MainViewModel"/>
</ResourceDictionary>
</Window.Resources>
This worked
Move the
<vieModel:MainWindowViewModel x:Key="MainViewModel"/>
line to inside of ResoruceDictonary like below:. Then you don't need to enter the key x:Key="ButtonStyle" and then style will be applied
<Window.Resources>
<ResourceDictionary >
<ResourceDictionary.MergedDictionaries>
<ResourceDictionary Source="GlassButton.xaml"/>
</ResourceDictionary.MergedDictionaries>
<vieModel:MainWindowViewModel x:Key="MainViewModel"/>
</ResourceDictionary>
</Window.Resources>

Window-Size from Resource not possible? - WPF [duplicate]

I have a ResourceDictionary that contains Style definitions for controls used within my application.
All of the styles are applied properly to the controls in the window...but the style in the ResourceDictionary for the window itself is not being applied.
This is the XAML in my ResourceDictionary that contains the style that I want to apply to my window:
<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:primatives="clr-namespace:System.Windows.Controls.Primitives;assembly=PresentationFramework"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
<Style TargetType="{x:Type Window}">
<Setter Property="Background" Value="#FF121212"></Setter>
<Setter Property="Height" Value="768"></Setter>
<Setter Property="Width" Value="1024"></Setter>
</Style>
<!-- .... -->
</ResourceDictionary>
This is the XAML for the window that I am working with (trying to get this style to apply):
<Window x:Class="TryingStyles"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="TryingStyles">
<Window.Resources>
<ResourceDictionary>
<ResourceDictionary.MergedDictionaries>
<ResourceDictionary Source="Resources/StylesDictionary.xaml" />
</ResourceDictionary.MergedDictionaries>
</ResourceDictionary>
</Window.Resources>
<StackPanel>
<StackPanel Orientation="Horizontal">
<Label Content="Label" Height="28" HorizontalAlignment="Left" Margin="12,12,0,0" Name="Label1" VerticalAlignment="Top" />
<TextBox Height="23" HorizontalAlignment="Left" Margin="56,14,0,0" Name="TextBox1" VerticalAlignment="Top" Width="120" />
</StackPanel>
<StackPanel Orientation="Horizontal">
<TabControl Height="206" HorizontalAlignment="Left" Margin="12,43,0,0" Name="TabControl1" VerticalAlignment="Top" Width="250">
<TabItem Header="TabItem1" Name="TabItem1">
<Grid></Grid>
</TabItem>
</TabControl>
<GroupBox Header="GroupBox1" Margin="268,43,12,12" Width="396"></GroupBox>
</StackPanel>
</StackPanel>
</Window>
It appears that the style for the window is applied when I view the window in the IDE's "Design view" but when I run the application the style is not applied.
Does anyone know what I'm doing wrong?
It appears that there is no proper solution to your problem. TargetType in Styles doesn't manage derived types.
Here are two alternatives :
You can put a key in your style and apply the style to all your Windows.
<!-- Resource file -->
<ResourceDictionary ...>
<Style TargetType="{x:Type Window}" x:Key="WindowDefaultStyle">
<!-- .... -->
</Style>
</ResourceDictionary>
<!-- Window file -->
<Window Style="{DynamicResource ResourceKey=WindowDefaultStyle}">
Or you can use the BasedOn property of the Style.
<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:my="clr-namespace:WpfApplication1">
<Style TargetType="{x:Type Window}" x:Key="BaseStyle">
<Setter Property="Background" Value="#FF121212"></Setter>
<Setter Property="Height" Value="768"></Setter>
<Setter Property="Width" Value="1024"></Setter>
</Style>
<!-- Inherit from the BaseStyle and define for the MainWindow class -->
<Style TargetType="{x:Type my:MainWindow}" BasedOn="{StaticResource ResourceKey=BaseStyle}" />
</ResourceDictionary>
It's very strange that it works with the designer but not when the application runs.
The problem seems to be the TargetType of your Style. Wpf seems not be able to match the Window class with your derivated class TryingStyles.
Change your TargetType and it will work :
<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:primatives="clr-namespace:System.Windows.Controls.Primitives;assembly=PresentationFramework"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:my="clr-namespace:WpfApplication1">
<Style TargetType="{x:Type my:TryingStyles}">
<Setter Property="Background" Value="#FF121212"></Setter>
<Setter Property="Height" Value="768"></Setter>
<Setter Property="Width" Value="1024"></Setter>
</Style>
<!-- .... -->
</ResourceDictionary>
I'm quite late to the party here, but I found a solution to have Style TargetType="{x:Type Window}" apply to every window application-wide, as one would expect. For the record, the reason this doesn't work is because each window you create is not a Window but a new type that derives from window (e.g. "MainWindow"), and Style's TargetType doesn't apply to derived classes. Anyway:
First, ensure your App.xaml has a Startup property defined; so inside the <Application> tag you'd add Startup="Application_Startup" or whatever you want to call the startup method.
Then, inside App.xaml.cs add:
private void Application_Startup(object sender, StartupEventArgs e)
{
FrameworkElement.StyleProperty.OverrideMetadata(typeof(Window), new FrameworkPropertyMetadata
{
DefaultValue = Application.Current.FindResource(typeof(Window))
});
}
where the method name matches whatever you listed as the Startup property in App.xaml. And of course, if you already have an existing startup method being run, just add the code contained within to that.
This basically just fixes it so that keyless Styles targeting "Window" will apply their changes to every window in your application, as you probably expected would occur without this code snippet. (That is of course assuming your style is already scoped application-wide, for example by containing it within a ResourceDictionary that is merged into App.xaml.)

How to place styles in separate .xaml files

I have an application with a large number of styles that are currently duplicated in the .xaml for each window of the application. I would like to be able to reference one file called UiStyles.xaml that contains all of the styles for the application.
After reading a ton of answered questions on here and Google I've tried this:
ButtonStyle.xaml:
<Style TargetType="{x:Type Button}" x:Key="ButtonStyle">
<Setter Property="Background" Value="Red"/>
<Setter Property="FontSize" Value="48"/>
</Style>
</ResourceDictionary>
UiStyles.xaml:
<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
<ResourceDictionary.MergedDictionaries>
<ResourceDictionary Source="ButtonStyle.xaml"/>
</ResourceDictionary.MergedDictionaries>
<Style TargetType="Control" /> <!-- Added this based on other user's suggestions to account for .net 4 bug -->
</ResourceDictionary>
MainWindow.xaml:
<Window x:Class="TestingGround.UI.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 Source="Resources/UIStyles.xaml"/>
</Window.Resources>
<Grid>
<Button Click="ButtonBase_OnClick" Content="Test Text"/>
</Grid>
</Window>
But my button style is not being applied! What am I doing wrong?
Note when you apply a key to a style, you have to explicitly apply it to the control so
<Button Click="ButtonBase_OnClick"
Content="Test Text"
Style={StaticResource ButtonStyle} />
However if you want all buttons to default to the style remove the x:key="ButtonStyle".
<Style TargetType="...">
You have created your button style with an x:Key, but are not referencing that in your button instance.
You need to set the "Style" property of the button like so:
<Button Click="ButtonBase_OnClick" Style="{StaticResource ButtonStyle}" Content="Test Text"/>

To call converter from ControlTemplate string

I'm trying to bind controlTemplate to in generic.xaml.My controlTemplate has converter in it.While binding,its throwing an exception as Provide value on 'System.Windows.Markup.StaticResourceHolder' threw an exception.
In MyView.cs
templateString = #"<ControlTemplate xmlns=""http://schemas.microsoft.com/winfx/2006/xaml/presentation"" xmlns:x=""http://schemas.microsoft.com/winfx/2006/xaml"" >
<Canvas><Polygon Points=""{Binding Size,Converter={StaticResource SizeConverter}}"" Fill=""red""/></Canvas>
</ControlTemplate>";
this.Template = XamlReader.Load(new System.Xml.XmlTextReader(new StringReader(templateString ))) as ControlTemplate;
In generic.xaml
<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:src="clr-namespace:MySample"
xmlns:vsm="clr-namespace:System.Windows;assembly=PresentationFramework"
xmlns:srcview="clr-namespace:MySample.Views"
xmlns:converters="clr-namespace:MySample.Converters"
>
<converters:SizeConverter x:Key="SizeConverter" />
<Style TargetType="{x:Type srcview:MyView}">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type srcview:MyView}">
<Canvas>
<ContentControl Template="{TemplateBinding Template}" Name="contentControl" >
</ContentControl>
</Canvas>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</ResourceDictionary>
How to fix this issue??
One normally gets this problem when the static resources are not defined before referencing them.
For a test, try reading an xaml usercontrol with a static resource defined in the resources section of the xaml. If that works then you know the problem is not with referencing the converter, but rather when and were it is defined.
A faster way to ensure that the converter is actually being loaded is to put it in the app.xaml. This will ensure that the resource dictionary is loaded at startup. Here follows an example:
<Application x:Class="TeslaFrame.App"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:metro="http://schemas.codeplex.com/elysium"
>
<Application.Resources>
<ResourceDictionary>
<ResourceDictionary.MergedDictionaries>
<ResourceDictionary Source="/Elysium;component/Themes/Generic.xaml"/>
<ResourceDictionary>
<BooleanToVisibilityConverter x:Key="globalBoolToVisConverter" />
</ResourceDictionary>
</ResourceDictionary.MergedDictionaries>
</ResourceDictionary>
</Application.Resources>
</Application>

Reference Main Window's Dictionary from Resource Dictionary

I have a WPF Window:
<Window x:Class="MyUI.MainWindow"
and so on>
<Window.Resources>
<ResourceDictionary>
<Style TargetType="{x:Type s:SurfaceListBox}" x:Key="FatherStyle" >
</ResourceDictionary>
</Window.Resources>
</Window>
I have a resource dictionary in MyResourceDictionary.xaml:
<ResourceDictionary xmlns="........."
and so on >
<Style TargetType="{x:Type s:SurfaceListBox}" x:Key="ChildStyle" BasedOn="{StaticResource FatherStyle}" />
</ResourceDictionary>
But when I try to reference ChildStyle from MyUI.Window:
<Window as shown in 1st block of code above>
<s:SurfaceListBox Style="{StaticResource ResourceKey=ChildStyle}" />
</Window>
It tells me that it can't find FatherStyle. I read here and merged the dictionary in MyResourceDictionary.xaml:
<ResourceDictionary xmlns="........."
and so on >
<ResourceDictionary.MergedDictionaries>
<ResourceDictionary Source="MainWindow.xaml" />
</ResourceDictionary.MergedDictionaries>
<Style ChildStyle as shown above />
</ResourceDictionary>
Now it tells me it can't find ChildStyle. How do I reference this properly?
You can't reference a resource dictionary contained in a Window-type XAML file, from another file. What you need to do is create a separate resource dictionary, "Shared.xaml" or whatever:
<ResourceDictionary ... >
<Style TargetType="{x:Type s:SurfaceListBox}" x:Key="FatherStyle" >
</ResourceDictionary>
Now reference the shared one from your main window:
... and also from "MyResourceDictionary.xaml":
<ResourceDictionary xmlns="........."
and so on >
<ResourceDictionary.MergedDictionaries>
<ResourceDictionary Source="Shared.xaml" />
</ResourceDictionary.MergedDictionaries>
<Style TargetType="{x:Type s:SurfaceListBox}" x:Key="ChildStyle" BasedOn="{StaticResource FatherStyle}" />
</ResourceDictionary>
And now in your "MyUI.xaml" window, you should be able to access the "ChildStyle" as you expected, by referencing "MyResourceDictionary":
<ResourceDictionary xmlns="........."
and so on >
<ResourceDictionary.MergedDictionaries>
<ResourceDictionary Source="MyResourceDictionary.xaml" />
</ResourceDictionary.MergedDictionaries>
<s:SurfaceListBox Style="{StaticResource ResourceKey=ChildStyle}" />
</ResourceDictionary>

Categories

Resources