Search code examples
c#wpfvisual-studio-2022resourcedictionary.net-4.8

Window style from an external (dll) resource dictionary doesn't apply in design mode


I created an external control library which holds some resource dictionaries etc. My problem is when I try to apply a style on a Window element. The style's changes are visible only when running, and not in the Visual Studio designer.

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?


Solution

  • 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/

    Edit

    Having tried this with the code supplied, there's a complication here with usage of x:Type Window.

    MainWindow is not a window, it's a MainWindow.

    The designer doesn't seem to want to work out MainWindow inherits from Window.

    If I change that style to:

    <Style x:Key="MainWindow_Style" TargetType="{x:Type Control}">
        <Setter Property="Background" Value="Green"/>
    </Style>
    

    This then works for me in my designer.

    enter image description here