Reputation: 49
I'm having an issue regarding referencing ResourceDictionaries (RD) across multiple assemblies.
The concrete issue I'm having at the moment is that the resources and styles are being applied to the LoginWindow at design-time but not at runtime.
I would also like to know for sure if RDs/resources work in the same manner that the DataContext works.
I'm kind of at wit's end and I assume I'm missing some fundamental knowledge of how WPF handles RDs and resources etc
For context, I have two assemblies I'm working with.
The ControlsAndResources assembly contains 5 simple RDs. These are all placed in /Styles/Default
The Login assembly contains the LoginWindow.xaml. (This contains a reference to the 'Package.xaml' with the intent that the implicit styles will apply to the 'Textblock', 'Textbox', and 'Button' contained within the 'LoginWindow' - They do but only at design-time, not at runtime)
I commented out a reference to a "DefaultStyles.xaml" RD which literally just encapsulates the same "Package.xaml" RD. For some reason I thought the solution would be to create a physical RD in the same assembly which then references the RD that I wanted from the different assembly. Nope.
I'm fairly proficient and comfortable with WPF, this topic being the exception as I've only started extracting my styles to separate RDs. I put it off because it seemed like a headache to deal with and manager. So far it seems I'm right. However I decided to start this in order to really adhere to the DRY principle. That being said, based off the code present, though trivial, if anyone has suggestions for better adhering to the DRY principle (or any suggestions really) then I'm all ears.
Thanks.
PS- I tried changing everything from StaticResource to DynamicResource but that just throws an exception, regardless of where I change it.
System.Windows.Markup.XamlParseException: 'A 'DynamicResourceExtension' cannot be set on the 'BasedOn' property of type 'Style'. A 'DynamicResourceExtension' can only be set on a DependencyProperty of a DependencyObject.'
~~~~~~~~~~~~~~~~~~~~ Base.xaml ~~~~~~~~~~~~~~~~~~~~
<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="clr-namespace:ControlsAndResources.Styles.Default">
<Style TargetType="{x:Type FrameworkElement}" x:Key="BaseDefaultFrameworkElement">
<Setter Property="Margin" Value="5"/>
</Style>
<Style TargetType="{x:Type Control}" x:Key="BaseDefaultControl" BasedOn="{StaticResource BaseDefaultFrameworkElement}">
<Setter Property="Padding" Value="5"/>
</Style>
</ResourceDictionary>
~~~~~~~~~~~~~~~~~~~~ Package.xaml ~~~~~~~~~~~~~~~~~~~~
<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="clr-namespace:ControlsAndResources.Styles.Default">
<ResourceDictionary.MergedDictionaries>
<ResourceDictionary Source="/ControlsAndResources;component/Styles/Default/Base.xaml"/>
<ResourceDictionary Source="/ControlsAndResources;component/Styles/Default/Buttons.xaml"/>
<ResourceDictionary Source="/ControlsAndResources;component/Styles/Default/Textblocks.xaml"/>
<ResourceDictionary Source="/ControlsAndResources;component/Styles/Default/Textboxes.xaml"/>
<ResourceDictionary>
<Style TargetType="Button" BasedOn="{StaticResource DefaultButtons}"/>
<Style TargetType="TextBlock" BasedOn="{StaticResource DefaultTextblocks}"/>
<Style TargetType="TextBox" BasedOn="{StaticResource DefaultTextboxes}"/>
</ResourceDictionary>
</ResourceDictionary.MergedDictionaries>
</ResourceDictionary>
~~~~~~~~~~~~~~~~~~~~ Buttons.xaml ~~~~~~~~~~~~~~~~~~~~
<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="clr-namespace:ControlsAndResources.Styles.Default">
<ResourceDictionary.MergedDictionaries>
<ResourceDictionary Source="/ControlsAndResources;component/Styles/Default/Base.xaml"/>
<ResourceDictionary>
<Style TargetType="Button" x:Key="DefaultButtons" BasedOn="{StaticResource BaseDefaultControl}"/>
</ResourceDictionary>
</ResourceDictionary.MergedDictionaries>
</ResourceDictionary>
~~~~~~~~~~~~~~~~~~~~ Textblocks.xaml ~~~~~~~~~~~~~~~~~~~~
<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="clr-namespace:ControlsAndResources.Styles.Default">
<ResourceDictionary.MergedDictionaries>
<ResourceDictionary Source="/ControlsAndResources;component/Styles/Default/Base.xaml"/>
<ResourceDictionary>
<Style TargetType="TextBlock" x:Key="DefaultTextblocks" BasedOn="{StaticResource BaseDefaultFrameworkElement}"/>
</ResourceDictionary>
</ResourceDictionary.MergedDictionaries>
</ResourceDictionary>
~~~~~~~~~~~~~~~~~~~~ Textboxes.xaml ~~~~~~~~~~~~~~~~~~~~
<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="clr-namespace:ControlsAndResources.Styles.Default">
<ResourceDictionary.MergedDictionaries>
<ResourceDictionary Source="/ControlsAndResources;component/Styles/Default/Base.xaml"/>
<ResourceDictionary>
<Style TargetType="TextBox" x:Key="DefaultTextboxes" BasedOn="{StaticResource BaseDefaultControl}"/>
</ResourceDictionary>
</ResourceDictionary.MergedDictionaries>
</ResourceDictionary>
~~~~~~~~~~~~~~~~~~~~ LoginWindow.xaml ~~~~~~~~~~~~~~~~~~~~
<Window x:Class="Login.LoginWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="clr-namespace:Login"
SizeToContent="WidthAndHeight"
Title="{Binding WindowTitle, FallbackValue=Login, TargetNullValue=Login}">
<Window.Resources>
<ResourceDictionary Source="pack://application:,,,/ControlsAndResources;component/Styles/Default/Package.xaml"/>
<!--<ResourceDictionary Source="pack://application:,,,/Login;component/Resources/XAML/DefaultStyles.xaml"/>-->
</Window.Resources>
<Grid>
<StackPanel>
<TextBlock>This is a textblock</TextBlock>
<Button>This is a button</Button>
<TextBox>This is a textbox</TextBox>
</StackPanel>
</Grid>
</Window>
~~~~~~~~~~~~~~~~~~~~ DefaultStyles.xaml ~~~~~~~~~~~~~~~~~~~~
<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="clr-namespace:Login.Resources.XAML">
<ResourceDictionary.MergedDictionaries>
<ResourceDictionary Source="/ControlsAndResources;component/Styles/Default/Package.xaml"/>
</ResourceDictionary.MergedDictionaries>
</ResourceDictionary>
Upvotes: 0
Views: 30
Reputation: 169230
The implicit styles in Package.xaml
should be defined in the merged ResourceDictionary
itself. Try this:
<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="clr-namespace:ControlsAndResources.Styles.Default">
<ResourceDictionary.MergedDictionaries>
<ResourceDictionary Source="/ControlsAndResources;component/Styles/Default/Base.xaml"/>
<ResourceDictionary Source="/ControlsAndResources;component/Styles/Default/Buttons.xaml"/>
<ResourceDictionary Source="/ControlsAndResources;component/Styles/Default/Textblocks.xaml"/>
<ResourceDictionary Source="/ControlsAndResources;component/Styles/Default/Textboxes.xaml"/>
</ResourceDictionary.MergedDictionaries>
<Style TargetType="Button" BasedOn="{StaticResource DefaultButtons}"/>
<Style TargetType="TextBlock" BasedOn="{StaticResource DefaultTextblocks}"/>
<Style TargetType="TextBox" BasedOn="{StaticResource DefaultTextboxes}"/>
</ResourceDictionary>
Upvotes: 1