4

I'm trying to place my WPF styles in a separate library, but at a little lost as to how this is best achieved. This is what I've done thus far:

  1. Created a new Class Library project and added references PresentationCore, PresentationFramework, System.Xaml and WindowsBase
  2. Created file "MyStyles.xaml" in this class library project with the following content:

    <ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
                xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
    
        <Style TargetType="Button" x:Key="MyButtonStyle">
            <Setter Property="Background" Value="Transparent"/>
        </Style>
    </ResourceDictionary>
    
  3. Built the project.

  4. Created a new WPF application project, and referenced the library built above.

  5. In App.xaml attempted to reference the resource dictionary in the libarary as follows:

    `<ApplicationResources>
    <ResourceDictionary>
        <ResourceDictionary.MergedDictionaries>
            <ResourceDictionary Source="pack://application:,,,/MyCustomWpfStyles;component/MyStyles.xaml"/>
        </ResourceDictionary.MergedDictionaries>
    </ResourceDictionary>
    

    `

  6. At this point VS intellisense is telling that an error occurred while finding the resource dictionary, although the application builds without problem.

  7. Even if I am able to load the resource dictionary, I'm not sure how to use it with a control, e.g., <Button Style="What goes here??" />

Looked over the internet, but can't seem to find a good example of how to package styles up into separate dll. Any pointers?

James B
  • 8,975
  • 13
  • 45
  • 83

1 Answers1

3
  1. Don't blindly trust VS intelli-sense to give you correct error messages at all times. There might be something wrong but I have seen VS not being able to handle multiple projects in the same solution under all circumstances. Ignore for now if it is just a warning. If it is a proper error and it is not able to compile, build the control library in a separate solution and set a proper reference to the dll in the client app.

  2. Use Style="{StaticResource MyButtonStyle}"

Also have a look at ResourceDictionary in a separate assembly It explains how to use resources in other types of assemblies and in other locations.

Here is code that works on my machine:

In a class library project WpfControlLibrary1, a file in the root folder named "Dictionary1.xaml":

<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
                    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
    <Style TargetType="Button"
           x:Key="Demo1">
        <Setter Property="BorderBrush"
                Value="Red" />
        <Setter Property="BorderThickness"
                Value="10" />
        <Setter Property="Background"
                Value="Transparent" />
    </Style>
</ResourceDictionary>

Note that setting the Background property might not work when the template used to draw the button does not use the Background property. The fancy gradient button template that WPF uses on Windows 7 does not do that but the flat one on Windows 8.1 does. That is why I added a big red border so that the style might show up partially.

In another solution, a Wpf application with a reference to the previous dll (not the project)

<Window x:Class="WpfApplication1.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>
            <ResourceDictionary.MergedDictionaries>
                <ResourceDictionary Source="pack://application:,,,/WpfControlLibrary1;component/Dictionary1.xaml" />
            </ResourceDictionary.MergedDictionaries>
        </ResourceDictionary>
    </Window.Resources>
    <Grid>
        <Button Content="Button"
                Style="{StaticResource ResourceKey=Demo1}"
                HorizontalAlignment="Left"
                Margin="139,113,0,0"
                VerticalAlignment="Top"
                Width="75" />
    </Grid>
</Window>

Moving the merged dictionary to the app object works as well:

<Application x:Class="WpfApplication1.App"
             xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
             xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
             StartupUri="MainWindow.xaml">
    <Application.Resources>
        <ResourceDictionary>
            <ResourceDictionary.MergedDictionaries>
                <ResourceDictionary Source="pack://application:,,,/WpfControlLibrary1;component/Dictionary1.xaml" />
            </ResourceDictionary.MergedDictionaries>
        </ResourceDictionary>
    </Application.Resources>
</Application>
Community
  • 1
  • 1
Emond
  • 50,210
  • 11
  • 84
  • 115
  • Also, if you'd like all your buttons to have the style that you have defined, simply omit the `x:Key` attribute. – Gimly May 05 '15 at 12:44
  • Thanks. Still no joy here though. Whilst the application builds, no matter what colour I set the background property in MyStyles.xaml to, I never seem to get it in my WPF application. Can't help I'm missing something simple - are you aware of any good examples of how to do this? – James B May 05 '15 at 12:53
  • @JamesB - I added a working example to my answer. Make sure all paths and names are correct. – Emond May 05 '15 at 13:43
  • @JamesB - I also added a special remark about setting a button's background. Be sure to read that. – Emond May 05 '15 at 13:46
  • @JamesB - I added a reference to a similar question that might solve your problem if the type of assembly (or resource) is different. – Emond May 05 '15 at 18:48
  • **Experience With Visual Studio 15:** *Project C* adds Resources from *Project B* via `Application.Resources`. *Project C* also starts MainWindow.xaml of *Project A* via `StartupUri` *(Package Syntax)*. Actually the Designer is mostly unable to correctly resolve those resources and shows a Warning. The consequence is, that you are not able to use the Designer properly, as Styles and Images from your Resources are not rendered. When the Application is executed, everything works fine. IMHO it's not worth the effort. Just simplify your dependencies. – LuckyLikey Apr 11 '17 at 11:53