Shared project with resource dictionary (xaml)

2019-02-25 06:08发布

问题:

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:

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?

回答1:

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"),
};


回答2:

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:

And the correct build action is available:

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.)



回答3:

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);