question

Martijnvangils-7723 avatar image
0 Votes"
Martijnvangils-7723 asked ·

Issues using ResourceDictionary in a C# class library

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-wpf
init-class.jpg (19.7 KiB)
maincommand.jpg (36.8 KiB)
10 |1000 characters needed characters left characters exceeded

Up to 10 attachments (including images) can be used with a maximum of 3.0 MiB each and 30.0 MiB total.

AlexLi-MSFT avatar image
0 Votes"
AlexLi-MSFT answered ·

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.


· 1 · Share
10 |1000 characters needed characters left characters exceeded

Up to 10 attachments (including images) can be used with a maximum of 3.0 MiB each and 30.0 MiB total.

Hi @AlexLi-MSFT ,

There is no problem with adding a ResourceDictionary. The problem is that my WPF Views can't resolve styles I add to the ResourceDictionary.


7539-screenshot-1.jpg


0 Votes 0 · ·
screenshot-1.jpg (100.2 KiB)
AlexLi-MSFT avatar image
0 Votes"
AlexLi-MSFT answered ·

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}"/>
· 1 · Share
10 |1000 characters needed characters left characters exceeded

Up to 10 attachments (including images) can be used with a maximum of 3.0 MiB each and 30.0 MiB total.

Thanks you for your answer, but where are you declaring <Application.Resources> in your project? I only have an "ActivationView.xaml" and "LocationView.xml" both of which the root starts at <Window>. Do you create a new file to declare <Application.Resources>?

0 Votes 0 · ·