WPF How to load Dictionaries as Application does?

Code Wanderer 396 Reputation points
2020-03-25T11:12:34.373+00:00

I am converting application in to DLL (CLassLibrary) and therefore I cannot use App.Xaml (Application). Inside my Dictionaries I use StaticResources for Storyboards and animations. Unfortunately it is not possible to use DynamicResources for Storyboards and I have problem to load my Dictionaries due StaticResource.

When I create application and add resources to application and then to my UserControl, it will be loaded without problem, but if I not use application, it throw exception.

Here is code how I load Dictionaries. (btw this code is from simple example app for test)

namespace WGUI
{
    public class ResDict
    {
        public ResDict()
        {
            MainResources = new ResourceDictionary();
            List<Uri> uris = new List<Uri>();
            uris.Add(new Uri("pack://application:,,,/WGUI;component/Themes/Dictionary3.xaml")); // Contain Colors
            uris.Add(new Uri("pack://application:,,,/WGUI;component/Themes/Dictionary1.xaml"));
            uris.Add(new Uri("pack://application:,,,/WGUI;component/Themes/Dictionary2.xaml")); // Contain StaticResource to Colors from Dictionary3
            foreach (var u in uris)
            {
                ResourceDictionary r = new ResourceDictionary();
                MainResources.MergedDictionaries.Add(r);
            }
        }

        private ResourceDictionary MainResources = null;
        public ResourceDictionary GetDictionary
        {
            get { return MainResources; }
        }
    }
}

    public UserControl2()
    {
        try
        {
            mResources = new ResDict();
            this.Resources = mResources.GetDictionary;
        }
        catch (Exception e)
        {
            MessageBox.Show(e.ToString());
        }
        InitializeComponent();
    }

Question is:
How can be Dictionary loaded like Application does? Application doesn't have problem load StaticResource but Resource from UserControl does.

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,679 questions
{count} votes

Accepted answer
  1. Peter Fleischer (former MVP) 19,231 Reputation points
    2020-03-26T20:05:04.077+00:00

    Hi, in your download file your "ButtonStyle2" don't know colors (in Dictionary3.xaml). Try following demo:

    XAML MainWindow
    
    <Window x:Class="WpfApp1.Window19"
            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:WpfApp1"
            xmlns:uc="clr-namespace:WpfControlLibrary1;assembly=WpfControlLibrary1"
            mc:Ignorable="d"
            Title="Window19" Height="450" Width="800">
      <Grid>
        <uc:Window19UC1/>
      </Grid>
    </Window>
    
    XAML UserControl (in WpfControlLibrary1):
    
    <UserControl x:Class="WpfControlLibrary1.Window19UC1"
                 xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
                 xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
                 xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
                 xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 
                 xmlns:local="clr-namespace:WpfControlLibrary1"
                 mc:Ignorable="d" 
                 d:DesignHeight="450" d:DesignWidth="800">
      <StackPanel>
        <TextBlock Text="UserControl 1a" Style="{StaticResource Style1}"/>
      </StackPanel>
    </UserControl>
    
    XAML Dictionary1 (in WpfControlLibrary1/Themes/Dictionary1.xaml)
    
    <ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
                        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
                        xmlns:local="clr-namespace:WpfControlLibrary1.Themes">
      <ResourceDictionary.MergedDictionaries>
        <ResourceDictionary Source="pack://application:,,,/WpfControlLibrary1;component/Themes/Dictionary2.xaml"/>
      </ResourceDictionary.MergedDictionaries>
      <Style x:Key="Style1" TargetType="TextBlock">
        <Setter Property="Background" Value="{StaticResource Red}"/>
      </Style>
    </ResourceDictionary>
    
    XAML Dictionary2 (in WpfControlLibrary1/Themes/Dictionary2.xaml)
    
    <ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
                        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
                        xmlns:local="clr-namespace:WpfControlLibrary1.Themes">
      <Brush x:Key="Red">#FFFF0000</Brush> 
    </ResourceDictionary>
    

    Code:

    using System;
    using System.Collections.Generic;
    using System.Windows;
    using System.Windows.Controls;
    using WpfControlLibrary19;
    
    namespace WpfControlLibrary1
    {
      /// <summary>
      /// Interaction logic for UserControl1.xaml
      /// </summary>
      public partial class Window19UC1 : UserControl
      {
        public Window19UC1()
        {
          try
          {
            var mResources = new ResDict();
            this.Resources = mResources.GetDictionary;
          }
          catch (Exception e) { MessageBox.Show(e.ToString()); }
          InitializeComponent();
        }
      }
    }
    
    namespace WpfControlLibrary19
    {
      public class ResDict
      {
        public ResDict()
        {
          MainResources = new ResourceDictionary();
          List<Uri> uris = new List<Uri>();
          uris.Add(new Uri("pack://application:,,,/WpfControlLibrary1;component/Themes/Dictionary1.xaml"));
          uris.Add(new Uri("pack://application:,,,/WpfControlLibrary1;component/Themes/Dictionary2.xaml"));
          foreach (var u in uris)
          {
            ResourceDictionary r = new ResourceDictionary();
            r.Source = u;
            MainResources.MergedDictionaries.Add(r);
          }
        }
    
        private ResourceDictionary MainResources = null;
        public ResourceDictionary GetDictionary
        {
          get { return MainResources; }
        }
      }
    }
    
    0 comments No comments

1 additional answer

Sort by: Most helpful
  1. Peter Fleischer (former MVP) 19,231 Reputation points
    2020-03-25T15:11:43+00:00

    Hi,
    you must set the Source of ResourceDictionary (r.Source = u;)!

     namespace WGUI
     {
         public class ResDict
         {
             public ResDict()
             {
                 MainResources = new ResourceDictionary();
                 List<Uri> uris = new List<Uri>();
                 uris.Add(new Uri("pack://application:,,,/WGUI;component/Themes/Dictionary3.xaml")); // Contain Colors
                 uris.Add(new Uri("pack://application:,,,/WGUI;component/Themes/Dictionary1.xaml"));
                 uris.Add(new Uri("pack://application:,,,/WGUI;component/Themes/Dictionary2.xaml")); // Contain StaticResource to Colors from Dictionary3
                 foreach (var u in uris)
                 {
                     ResourceDictionary r = new ResourceDictionary();
                     r.Source = u;
                     MainResources.MergedDictionaries.Add(r);
                 }
             }
    
             private ResourceDictionary MainResources = null;
             public ResourceDictionary GetDictionary
             {
                 get { return MainResources; }
             }
         }
     }