I have a WPF custom control library project structured as shown below, and I want reference the resource dictionary from this WPF ccl in another WPF app.
CustomUI/
├── CustomStyle/
│ ├── BasicComponents/
│ ├── Buttons/
│ │ ├── SmallButton.xaml
│ │ └── StandardButton.xaml
│ ├── ComboBox/
│ │ └── StandardComboBox.xaml
│ ├── PasswordBox/
│ └── StandardPasswordBox.xaml
├── MergedResourceDictionary.xaml
In the MergedResourceDictionary.xaml
at the bottom, I’ve already included the other 4 resource dictionaries.
Like this:
<ResourceDictionary.MergedDictionaries>
<ResourceDictionary Source="CustomStyle/BasicComponents/Buttons/SmallButton.xaml"/>
<ResourceDictionary Source="CustomStyle/BasicComponents/Buttons/StandardButton.xaml"/>
<ResourceDictionary Source="CustomStyle/BasicComponents/ComboBox/StandardComboBox.xaml"/>
<ResourceDictionary Source="CustomStyle/BasicComponents/PasswordBox/StandardPasswordBox.xaml"/>
</ResourceDictionary.MergedDictionaries>
When I try reference this MergedResourceDictionary.xaml
in the App.xaml
of another WPF app, I get an error saying the resource MergedResourceDictionary.xaml
could not be found.
The path is:
<Application.Resources>
<ResourceDictionary>
<ResourceDictionary.MergedDictionaries>
<ResourceDictionary Source="pack://application:,,,/CustomUI;component/MergedResourceDictionary.xaml"/>
</ResourceDictionary.MergedDictionaries>
</ResourceDictionary>
</Application.Resources>
However, if I use the path:
<Application.Resources>
<ResourceDictionary>
<ResourceDictionary.MergedDictionaries>
<ResourceDictionary Source="pack://application:,,,/CustomUI;component/CustomStyle/BasicComponents/Buttons/SmallButton.xaml"/>
</ResourceDictionary.MergedDictionaries>
</ResourceDictionary>
</Application.Resources>
it works perfectly.
I want to know if I did something wrong. For example, is it not allowed to use merged dictionaries this way?
--- SOLVED ---------------------------
I recreated the both projects and fixing a namespace issue, it worked.
Although I’m not sure the namespace issue is related to the problem I mentioned above, I’d like to share my perspective in case it helps others:
I have a habit of anizing C# classes into folders, such as "Scripts"
, which causes all the class use the namespace CustomUI.Scripts
, instead of CustomUI
(root namespace).This actually create a problem, clr-namespace not declared
in xaml.
I tried creating a C# class directly in the root directory and using CustomUI
, and the XAML system immediately worked again...
I think that in
"pack://application:,,,/xxxx;component/yyyy.xaml"
xxxx
is root namespace of the application rather than its project name
I’m not sure. Just for reference.
I have a WPF custom control library project structured as shown below, and I want reference the resource dictionary from this WPF ccl in another WPF app.
CustomUI/
├── CustomStyle/
│ ├── BasicComponents/
│ ├── Buttons/
│ │ ├── SmallButton.xaml
│ │ └── StandardButton.xaml
│ ├── ComboBox/
│ │ └── StandardComboBox.xaml
│ ├── PasswordBox/
│ └── StandardPasswordBox.xaml
├── MergedResourceDictionary.xaml
In the MergedResourceDictionary.xaml
at the bottom, I’ve already included the other 4 resource dictionaries.
Like this:
<ResourceDictionary.MergedDictionaries>
<ResourceDictionary Source="CustomStyle/BasicComponents/Buttons/SmallButton.xaml"/>
<ResourceDictionary Source="CustomStyle/BasicComponents/Buttons/StandardButton.xaml"/>
<ResourceDictionary Source="CustomStyle/BasicComponents/ComboBox/StandardComboBox.xaml"/>
<ResourceDictionary Source="CustomStyle/BasicComponents/PasswordBox/StandardPasswordBox.xaml"/>
</ResourceDictionary.MergedDictionaries>
When I try reference this MergedResourceDictionary.xaml
in the App.xaml
of another WPF app, I get an error saying the resource MergedResourceDictionary.xaml
could not be found.
The path is:
<Application.Resources>
<ResourceDictionary>
<ResourceDictionary.MergedDictionaries>
<ResourceDictionary Source="pack://application:,,,/CustomUI;component/MergedResourceDictionary.xaml"/>
</ResourceDictionary.MergedDictionaries>
</ResourceDictionary>
</Application.Resources>
However, if I use the path:
<Application.Resources>
<ResourceDictionary>
<ResourceDictionary.MergedDictionaries>
<ResourceDictionary Source="pack://application:,,,/CustomUI;component/CustomStyle/BasicComponents/Buttons/SmallButton.xaml"/>
</ResourceDictionary.MergedDictionaries>
</ResourceDictionary>
</Application.Resources>
it works perfectly.
I want to know if I did something wrong. For example, is it not allowed to use merged dictionaries this way?
--- SOLVED ---------------------------
I recreated the both projects and fixing a namespace issue, it worked.
Although I’m not sure the namespace issue is related to the problem I mentioned above, I’d like to share my perspective in case it helps others:
I have a habit of anizing C# classes into folders, such as "Scripts"
, which causes all the class use the namespace CustomUI.Scripts
, instead of CustomUI
(root namespace).This actually create a problem, clr-namespace not declared
in xaml.
I tried creating a C# class directly in the root directory and using CustomUI
, and the XAML system immediately worked again...
I think that in
"pack://application:,,,/xxxx;component/yyyy.xaml"
xxxx
is root namespace of the application rather than its project name
I’m not sure. Just for reference.
- It's great that you solved your issue, but please don't put the Answer in the Question. Kindly remove that block and post a Self-Answer instead. – IV. Commented Jan 20 at 19:20
- ...but now I seem to recall that requires >15 reputation... – IV. Commented Jan 20 at 19:25
- I was also confused, and I tried to click "Answer" and he warned me that if I needed to add more information I could use the "Edit" function, so I put it in the question. I will fix it though, and I appreciate your help. – Adriano0113 Commented Jan 21 at 20:49
- Thx for accepting my answer in the meantime! You're always free to change that designation in the future. – IV. Commented Jan 21 at 21:20
1 Answer
Reset to default 0I don't think you're doing anything conceptually wrong, and I suspect some kind of path typo perhaps. One strategy for debugging is to enumerate the binary markup resource names to see what's "actually there", using a snippet similar to this:
namespace Wpf.ClientApp
{
public partial class App : Application
{
protected override void OnStartup(StartupEventArgs e)
{
base.OnStartup(e);
if (AppDomain.CurrentDomain.GetAssemblies().FirstOrDefault(_ => _?.GetName()?.Name == "Wpf.CustomUI") is { } asm)
{
var debug = asm.GetManifestResourceNames().First();
if (asm.GetManifestResourceNames().FirstOrDefault(_ => _.EndsWith("resources")) is { } resource)
{
var resourceRoot = resource.Replace(".resources", string.Empty);
var resourceManager = new ResourceManager(resourceRoot, asm);
using (var resourceSet = resourceManager.GetResourceSet(System.Globalization.CultureInfo.CurrentCulture, true, true))
{
if (resourceSet != null)
{
foreach (DictionaryEntry entry in resourceSet)
{
Debug.WriteLine($"Key: {entry.Key}, Value Type: {entry.Value?.GetType()}");
}
}
}
}
}
}
}
}
When I use your text diagram to try and repro your hierarchy, I get this:
It enumerates as this:
Key: customstyle/basiccomponents/buttons/smallbutton.baml, Value Type: System.IO.UnmanagedMemoryStream
Key: mergedresourcedictionary.baml, Value Type: System.IO.UnmanagedMemoryStream
Key: customstyle/basiccomponents/buttons/standardbutton.baml, Value Type: System.IO.UnmanagedMemoryStream
Key: customstyle/basiccomponents/combobox/standardcombobox.baml, Value Type: System.IO.UnmanagedMemoryStream
Key: customstyle/basiccomponents/passwordbox/standardpasswordbox.baml, Value Type: System.IO.UnmanagedMemoryStream
And it works if I do this:
<Application x:Class="Wpf.ClientApp.App"
xmlns="http://schemas.microsoft/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft/winfx/2006/xaml"
xmlns:local="clr-namespace:Wpf.ClientApp"
StartupUri="MainWindow.xaml">
<Application.Resources>
<ResourceDictionary>
<ResourceDictionary.MergedDictionaries>
<ResourceDictionary Source="pack://application:,,,/Wpf.CustomUI;component/MergedResourceDictionary.xaml" />
</ResourceDictionary.MergedDictionaries>
</ResourceDictionary>
</Application.Resources>
</Application>