Issues using ResourceDictionary in a C# class library

Martijn van gils 1 Reputation point
2020-04-20T08:47:13.967+00:00

I'm having trouble with reusing styles for WPF/XAML in my project. Just to give you some context. I am making a plugin for Revit, architectural/3D/CAD software used by many architects/contractors worldwide. To make a plugin for Revit, the Revit API allows you to call class/methods from a C# class library, so not a WPF application.

So how does the plugin work?

  • When Revit is starting up, it calls the Init class which adds the plugin to the program (and the needed buttons in the UI)

7575-init-class.jpg

  • After startup you can press a button in the Revit UI, which calls the MainCommand class, which then opens the LocationView.xaml WPF window I created.

7524-maincommand.jpg

So the issue I can't seem to solve: Like LocationView.xaml, I would like to make multiple WPF windows (a window to activate the plugin, a window with plugin settings), which would then share the same styling. I tried to make a ResourceDictionary to share styles across the plugin, but my XAML elements can't seem to find the styling in that ResourceDictionary.

So this is some code I tried, but doesn't work:
InputStyles.xaml

<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"  
                xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">  
<Style x:Key="SearchInputStyle" TargetType="{x:Type TextBox}">  
    <Setter Property="Height" Value="30"/>  
    <Setter Property="FontWeight" Value="Bold" />  
    <Setter Property="Template">  
        <Setter.Value>  
            <ControlTemplate TargetType="{x:Type TextBox}">  
                <Border CornerRadius="15" Background="White" BorderBrush="Transparent" x:Name="border">  
                    <Grid>  
                        <TextBox Text="{Binding Path=Text,  
                                            RelativeSource={RelativeSource TemplatedParent},   
                                            Mode=TwoWay,  
                                            UpdateSourceTrigger=PropertyChanged}"  
                             x:Name="textSource"   
                             Background="Transparent"   
                             Panel.ZIndex="2" />  
                            <TextBox Text="{TemplateBinding Tag}" Background="{TemplateBinding Background}" Panel.ZIndex="1">  
                                <TextBox.Style>  
                                    <Style TargetType="{x:Type TextBox}">  
                                        <Setter Property="Foreground" Value="Transparent"/>  
                                        <Style.Triggers>  
                                            <DataTrigger Binding="{Binding Path=Text, Source={x:Reference textSource}}" Value="">  
                                                <Setter Property="Foreground" Value="Gray"/>  
                                                <Setter Property="HorizontalContentAlignment" Value="Left"/>  
                                                <Setter Property="VerticalContentAlignment" Value="Center"/>  
                                            </DataTrigger>  
                                        </Style.Triggers>  
                                    </Style>  
                                </TextBox.Style>  
                            </TextBox>  
                    </Grid>  
                </Border>  
                <ControlTemplate.Triggers>  
                    <Trigger Property="IsMouseOver" Value="true">  
                        <Setter Property="BorderBrush" TargetName="border" Value="Red"/>  
                        <Setter Property="Foreground" Value="Red" />  
  
                    </Trigger>  
                    <Trigger Property="IsFocused" Value="true">  
                        <Setter Property="Foreground" Value="Blue" />  
                        <Setter Property="BorderBrush" TargetName="border" Value="Blue"/>  
                    </Trigger>  
                    <DataTrigger Binding="{Binding Path=Text}" Value="">  
                        <Setter Property="Text" Value="Vul een adres in"/>  
                    </DataTrigger>  
                </ControlTemplate.Triggers>  
            </ControlTemplate>  
        </Setter.Value>  
    </Setter>  
</Style>  

Dictionary.xaml

<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"  
                xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">  
<ResourceDictionary x:Key="MergedDictionaries">  
    <ResourceDictionary.MergedDictionaries>  
        <ResourceDictionary Source="Dictionaries/InputStyles.xaml"/>  
    </ResourceDictionary.MergedDictionaries>  
</ResourceDictionary>  

LocationView.xaml Window.Resources

 <Window.Resources>  
    <local:LocationView x:Key="mainViewDataSource" />  
    <FontFamily x:Key="Ubuntu">pack://application:,,,/Kalec.Enveo;component/src/Resources/Fonts/#Ubuntu</FontFamily>  
    <FontFamily x:Key="FontAwesomeSolid">pack://application:,,,/Kalec.Enveo;component/src/Resources/Fonts/#Font Awesome 5 Free Solid</FontFamily>  
    <FontFamily x:Key="FontAwesomeRegular">pack://application:,,,/Kalec.Enveo;component/src/Resources/Fonts/#Font Awesome 5 Free Regular</FontFamily>  
    <ResourceDictionary x:Key="dictionary" Source="pack://application:,,,/Kalec.Enveo;component/src/WPF/Styles/Dictionary.xaml" />  

And at last, trying to apply it to a TextBox

<StackPanel Margin="10,10,0,0" Orientation="Vertical">  
                <StackPanel Panel.ZIndex="10" Orientation="Horizontal"   
                    Name="SearchParameters">  
                    <TextBox Width="220" Style="{DynamicResource SearchInputStyle}"/>  
                    <Button FontFamily="{StaticResource FontAwesomeSolid}"   
                        Content="&#xf019;" Foreground="#31B192" Grid.ColumnSpan="2"   
                        Style="{DynamicResource LocationImport}"  
                        Margin="10, 0, 0, 0"/>  
                </StackPanel>  
                <Label Name="ErrorMessage" Visibility="Visible"></Label>  
                <StackPanel Orientation="Vertical" Visibility="Collapsed"   
                        Height="400" Width="300"  
                        Name="AddressList"></StackPanel>  
            </StackPanel>  

I've tried to apply it as DynamicResource and StaticResource, but I keep getting the error that the style could not be resolved, though my dictionary does get resolved in my Window.Resources.
One of the solutions I got is to add my Dictionary to App.xml, but I don't have that file, because these are views which are added to a C# class libary.

Windows Presentation Foundation
Windows Presentation Foundation
A part of the .NET Framework that provides a unified programming model for building line-of-business desktop applications on Windows.
2,667 questions
0 comments No comments
{count} votes

2 answers

Sort by: Most helpful
  1. Alex Li-MSFT 1,096 Reputation points
    2020-04-21T02:24:01.557+00:00

    Welcome to our Microsoft Q&A platform!

    Would you like to add Resources Dictionary to Class Library?

    1. right click your project(class library),select unload project
    2. right click your project again,select Edit xxxx
    3. add <ProjectTypeGuids>{60dc8134-eba5-43b8-bcc9-bb4bc16c2548};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}</ProjectTypeGuids>
      7613-annotation-2020-04-21-102014.png

    4.right click your project ,load project

    Now,you can add Resources Dictionary to Class Library.

    Thanks.


  2. Alex Li-MSFT 1,096 Reputation points
    2020-04-23T03:39:27.11+00:00

    I can resolve resource form class library,see my code:

    TestClassLibrary:

    <ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
                        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
                        xmlns:local="clr-namespace:TestClassLibrary">
        <Style TargetType="Button" x:Key="mystyle">
            <Setter Property="Background" Value="Red"/>
        </Style>
    
    </ResourceDictionary>
    

    main project:

      <Application.Resources>
            <ResourceDictionary>
                <ResourceDictionary.MergedDictionaries>
                    <ResourceDictionary Source="pack://application:,,,/TestClassLibrary;component/Dictionary1.xaml"/>
                </ResourceDictionary.MergedDictionaries>
            </ResourceDictionary>
        </Application.Resources>
    
    
     <Button  Content="Btn"  Style="{StaticResource mystyle}"/>