Shared project with resource dictionary (xaml)
Asked Answered
J

3

5

I am looking for a way to share ResourceDictionary between projects.

Adding new item to shared project doesn't offer resource dictionary. It can be created in other (main) project and dragged. But then I can't change its build options to Page:

enter image description here

The idea is to load resource dictionary like this

var dictionary = new ResourceDictionary();
dictionary.Source = new Uri("/WpfApplication91;component/Dictionary2.xaml", UriKind.Relative);

This is obviously fails currently with

An exception of type 'System.IO.IOException' occurred in PresentationFramework.dll but was not handled in user code

Additional information: Cannot locate resource 'dictionary2.xaml'.

Any ideas?

Jabberwocky answered 14/12, 2016 at 9:28 Comment(0)
J
4

It's possible to manually edit shared project to set build action for resource dictionary.

Shared project consists of Project.shproj and Project.projitems files, open second and locate dictionary there:

<ItemGroup>
  <None Include="$(MSBuildThisFileDirectory)Dictionary.xaml" />
</ItemGroup>

Add after that

<ItemGroup>
  <Page Include="$(MSBuildThisFileDirectory)Dictionary.xaml">
    <Generator>MSBuild:Compile</Generator>
    <SubType>Designer</SubType>
  </Page>
</ItemGroup>

it's a copy/paste thing from normal csproj for WPF project containing dictionary.

Seems to work, though this build action is not visible when project is loaded into Visual Studio. Adding files to shared project doesn't affect this manual change.

Now I can have shared project containing resource dictionary, yay!

Resource dictionary can be merged into application dictionaries like if it's located in the root of the project (to use as static/dynamic resource in xaml designer):

<Application.Resources>
    <ResourceDictionary >
        <ResourceDictionary.MergedDictionaries>
            <!-- doesn't really exists in project -->
            <ResourceDictionary Source="Dictionary.xaml" />
        </ResourceDictionary.MergedDictionaries>
    </ResourceDictionary>
</Application.Resources>

and/or loaded manually, e.g. using this pack Uri :

var dictionary = new ResourceDictionary()
{
     Source = new Uri("pack://application:,,,/FlexProperty.xaml"),
};
Jabberwocky answered 3/1, 2017 at 9:50 Comment(0)
V
3

I was having the same problem. There's a solution for including Xaml in shared projects which doesn't require editing the .projitems file directly.

You just have to add Xamarin to your Visual Studio installation. (I did it with VS Community 2015.)

You can now add xaml types via the usual Visual Studio dialog: Add Resource Dictionary

And the correct build action is available: Build action

Xaml in shared projects now compiles and runs as expected.

(Presumably this is there to support Xamarin Forms, but it works for any xaml document.)

Vender answered 22/2, 2017 at 14:51 Comment(6)
I added some screenshots.Vender
You are using shared project in UWP solution. It doesn't solve my WPF solution issue.Jabberwocky
You can add the shared project to any project you would normally be able to, including WPF projects.Vender
Sure, but then there is no Build option "Page", see screenshot in question and that's my problem.Jabberwocky
Yes, there is, if you install Xamarin. See my screenshot. I just tried adding the shared project to a WPF project and it works.Vender
I don't see wpf application on either of your screenshots ;)Jabberwocky
H
0

This issue is that you are putting the application name. You need the project name. Below is how to do it in both XAML and code

<UserControl.Resources>
    <ResourceDictionary>
        <ResourceDictionary.MergedDictionaries>
            <ResourceDictionary Source="/SharedProject1;Component/Dictionary2.xaml" />
        </ResourceDictionary.MergedDictionaries>
    </ResourceDictionary>
</UserControl.Resources>

Or

var dictionary = new ResourceDictionary();
dictionary.Source = new Uri("/SharedProject1;component/Dictionary2.xaml", UriKind.Relative);
Hengelo answered 14/12, 2016 at 13:51 Comment(5)
Nope, application name should work just fine. Replacing Dictionary2.xaml with Dictionary1.xaml will make my code working without problem, but my aim is to target dictionary in the shared project. Your change should make any difference, because build action is still None. You can create same project structure (wpf solution, add shared project, add resource dictionary, move it to shared project) and put code into main window constructor and see for yourself.Jabberwocky
did you try my response? Because your none shared project is also the name of the Application.Hengelo
"your none shared project is also the name of the Application" - I don't understand this. There is no need to try anything, it won't work for as long as build action still None.Jabberwocky
In the screen shots you shared, there are 2 projects, one shared and one not shared. the statement your highlighted was referencing the project that was not shared. It has the same name as your solution. So even though you are entering the Solution Name, it might be looking only at the project of the same name. This would also explain why replacing Dictionary2.xaml with Dictionary1.xaml would workHengelo
I see what you mean. My problem is not really that, but the build action. I provided example of use to show my intention in case someone will ask: "Why do you want this?" - "To use it like this in any other solution what will be using this shared project with this code".Jabberwocky

© 2022 - 2024 — McMap. All rights reserved.