steveh
Topic Author
Posts: 25
Joined: 07 Oct 2019, 12:50

Separating application resources across different assemblies

04 Jun 2020, 18:27

Hi guys,

I have a question about the proper way to separate themes / resources between several different assemblies. We use Blend to develop our UI. We have a project specifically for controls which might want to be shared between multiple games, let's call this project "Engine". I also want to provide a default style for these controls. We then have our "Game" assembly which references "Engine". In the GameApp.xaml file we merge in the resource dictionary from the Engine assembly. So just to clarify we have the following:
  • OurGameBlendUI.sln
    • Engine.csproj - This is the shared blend CSProj file which contains shared controls. Namespace is "Engine".
      • MyFirstEngineControl.cs
      • MySecondEngineControl.cs
      • EngineTheme.xaml - This provides a default style for MyFirstEngineControl and MySecondEngineControl
    • Game.csproj - This is the blend CSProj file specifically for our game. Namespace is "Game"
      • MyFirstGameControl.cs
      • GameApp.xaml
      • Game.xaml
      • GameTheme.xaml
The GameApp.xaml simply merges the engine and game themes together:
<Application x:Class="Game.GameApp" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
             StartupUri="Game.xaml">
    <Application.Resources>
        <ResourceDictionary>
            <ResourceDictionary.MergedDictionaries>
                <ResourceDictionary Source="pack://application:,,,/Engine;component/EngineTheme.xaml" />
                <ResourceDictionary Source="GameTheme.xaml" />
            </ResourceDictionary.MergedDictionaries>
        </ResourceDictionary>
    </Application.Resources>
</Application>
This works fine in Blend for any system control. For example, I can have a style defined in EngineTheme.xaml for a regular button as such:
<Style TargetType="Button">
    <Setter Property="Background" Value="Red" />
</Style>
And this works fine, any button in the Game project will default to having a red background. However, if I try to create a style for a control defined in the Engine project it gets trickier due to namespaces:
<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
                    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
                    xmlns:Engine="clr-namespace:Engine">
    <Style TargetType="{x:Type Engine:MyFirstEngineControl}">
        <Setter Property="Background" Value="Red" />
    </Style>
</ResourceDictionary>
This compiles and builds fine in the Engine project. However, when I try to build the Game project I get an error in the GameApp.xaml on the following line:
                <ResourceDictionary Source="pack://application:,,,/Engine;component/EngineTheme.xaml" />
The error is as follows:
Error	XDG0008	The name "MyFirstEngineControl" does not exist in the namespace "clr-namespace:Engine".	Game	EngineTheme.xaml	1	
The issue is the fact that the namespace declaration in the EngineTheme.xaml does not have an assembly reference. I can fix this by changing the namespace alias to the following:
 xmlns:Engine="clr-namespace:Engine;assembly=Engine"
But then this breaks when trying to build Engine.

I could split Engine into 2 projects:
  • EngineControls.csproj - Contains all the code for the controls
  • EngineTheme.csproj - Contains all the resource dictionary for the engine controls
Then that way the EngineTheme.xaml could implement the namespace alias as such:
xmlns:Engine="clr-namespace:Engine;assembly=EngineControls"
But this feels messy.

Do you have any suggestions for best practices regarding this? Am I just going about this the wrong way? It feels like I'm fighting with Blend so I get the impression I'm just doing something wrong.

Cheers,

-Steven
 
User avatar
sfernandez
Site Admin
Posts: 1918
Joined: 22 Dec 2011, 19:20

Re: Separating application resources across different assemblies

04 Jun 2020, 19:18

Hi Steven,

That is something that should work, otherwise control libraries wouldn't exist.
I just tried with a small sample (attached) containing a control library assembly and an application using it, and it compiles and runs fine.
Please let me know if you have anything different in your configuration, perhaps you didn't add a reference in the application (Game) to the control library (Engine) assembly?

Cheers.
Attachments
BlendResourcesTest.zip
(16.84 KiB) Downloaded 8 times
 
steveh
Topic Author
Posts: 25
Joined: 07 Oct 2019, 12:50

Re: Separating application resources across different assemblies

04 Jun 2020, 20:40

Cheers for the example Sergio. I double checked all the references and it was all set up correctly.

I found the issue though. The application type had accidentally been changed to Application. I checked everything put overlooked this :) I changed it back to class library and it started working again, so it's all good.

Cheers

-Steven
 
User avatar
sfernandez
Site Admin
Posts: 1918
Joined: 22 Dec 2011, 19:20

Re: Separating application resources across different assemblies

04 Jun 2020, 20:52

Great to hear it worked, thanks for the update.

Who is online

Users browsing this forum: No registered users and 1 guest