Use the App.xaml from a normal WPF project in a WP

2019-02-19 23:40发布

问题:

I have a WPF project with App.xaml (not a resource dictionary) with some material design stuff and a ViewModelLocator(MVVM) that looks like this:

<Application.Resources>
    <ResourceDictionary>
        <ResourceDictionary.MergedDictionaries>
            <ResourceDictionary Source="pack://application:,,,/MaterialDesignThemes.Wpf;component/Themes/MaterialDesignTheme.Light.xaml">
            </ResourceDictionary>
            <ResourceDictionary Source="pack://application:,,,/MaterialDesignThemes.Wpf;component/Themes/MaterialDesignTheme.Defaults.xaml">
            </ResourceDictionary>
            <!--<ResourceDictionary Source="pack://application:,,,/MaterialDesignColors;component/Themes/Recommended/Primary/MaterialDesignColor.DeepPurple.xaml">
            </ResourceDictionary>
            <ResourceDictionary Source="pack://application:,,,/MaterialDesignColors;component/Themes/Recommended/Accent/MaterialDesignColor.Lime.xaml">
            </ResourceDictionary>-->
            <!-- primary color -->
            <ResourceDictionary>
                <!-- include your primary palette -->
                <ResourceDictionary.MergedDictionaries>
                    <ResourceDictionary Source="pack://application:,,,/MaterialDesignColors;component/Themes/MaterialDesignColor.teal.xaml">
                    </ResourceDictionary>
                </ResourceDictionary.MergedDictionaries>
                <!--
                        include three hues from the primary palette (and the associated forecolours).
                        Do not rename, keep in sequence; light to dark.
                    -->
                <SolidColorBrush x:Key="PrimaryHueLightBrush"
                                 Color="{StaticResource Primary100}" />
                <SolidColorBrush x:Key="PrimaryHueLightForegroundBrush"
                                 Color="{StaticResource Primary100Foreground}" />
                <SolidColorBrush x:Key="PrimaryHueMidBrush"
                                 Color="{StaticResource Primary500}" />
                <SolidColorBrush x:Key="PrimaryHueMidForegroundBrush"
                                 Color="{StaticResource Primary500Foreground}" />
                <SolidColorBrush x:Key="PrimaryHueDarkBrush"
                                 Color="{StaticResource Primary700}" />
                <SolidColorBrush x:Key="PrimaryHueDarkForegroundBrush"
                                 Color="{StaticResource Primary700Foreground}" />
            </ResourceDictionary>
            <!-- secondary colour -->
            <ResourceDictionary>
                <!-- include your secondary pallette -->
                <ResourceDictionary.MergedDictionaries>
                    <ResourceDictionary Source="pack://application:,,,/MaterialDesignColors;component/Themes/MaterialDesignColor.teal.xaml">
                    </ResourceDictionary>
                </ResourceDictionary.MergedDictionaries>
                <!-- include a single secondary accent color (and the associated forecolour) -->
                <SolidColorBrush x:Key="SecondaryAccentBrush"
                                 Color="{StaticResource Accent200}" />
                <SolidColorBrush x:Key="SecondaryAccentForegroundBrush"
                                 Color="{StaticResource Accent200Foreground}" />
            </ResourceDictionary>
            <!-- Include the Dragablz Material Design style -->
            <ResourceDictionary Source="pack://application:,,,/Dragablz;component/Themes/materialdesign.xaml">
            </ResourceDictionary>

            <ResourceDictionary Source="Resources/CustomMaterialDesignControls.xaml" />

        </ResourceDictionary.MergedDictionaries>
        <!-- tell Dragablz tab control to use the Material Design theme -->
        <Style TargetType="{x:Type dragablz:TabablzControl}"
               BasedOn="{StaticResource MaterialDesignTabablzControlStyle}" />
        <vm:ViewModelLocator x:Key="Locator"
                             d:IsDataSource="True"
                             xmlns:vm="clr-namespace:**WPFProject**.ViewModels" />
    </ResourceDictionary>
</Application.Resources>

It works perfect when I create a Window in WPFProject.

But I also have a WPF Custome Library project. How can I acces the App.xaml from WPFProject in my Custom WPF project.

This is a Window.xaml in Custom WPF Library project:

<Window x:Class="**CustomWPFLibrary**.Views.PersonView"
    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"
    mc:Ignorable="d"
    xmlns:materialDesign="http://materialdesigninxaml.net/winfx/xaml/themes"
    xmlns:i="clr-namespace:System.Windows.Interactivity;assembly=System.Windows.Interactivity"
    TextElement.Foreground="{DynamicResource MaterialDesignBody}"
    TextElement.FontWeight="Regular"
    TextElement.FontSize="12"
    TextOptions.TextFormattingMode="Ideal"
    TextOptions.TextRenderingMode="Auto"
    Background="{DynamicResource MaterialDesignPaper}"
    FontFamily="{DynamicResource MaterialDesignFont}"
    Title=" eFenKa - PERSONEN"
    WindowStyle="SingleBorderWindow"
    ResizeMode="CanResize"
    WindowStartupLocation="CenterScreen"
    WindowState="Maximized"
    DataContext="{Binding PersonViewModel, Mode=OneWay, Source={StaticResource Locator}}">
<Grid>

</Grid>

Locator and the MaterialDesign stuff can't be resolved. Any ideas? Or is this even possible?

回答1:

TL;DR: I put an example on GitHub


Edit: a different GitHub user posted a decent article on this topic: article.


The Problem

There are two projects and you would like styling to be shown in the designer of both. To generalize:

  • a WpfApplication project (output type of WindowsApplication)
  • a CustomControls project (output type of ClassLibrary)

A Solution

I have seen posts suggesting that the App.xaml file be shared. Depending on how that is done, a circular dependency could be created or you could run into problems with trying to force a class library to contain an ApplicationDefinition. So instead, I suggest that you separate out your styling into a third project. Your solution structure will now look like:

  • a WpfApplication project (output type of WindowsApplication)
  • a CustomControls project (output type of ClassLibrary)
  • a StylesProject project (output type of ClassLibrary)

To have these styles appear in the design view of the CustomControls project and to be used by your WpfApplication:

  1. As always, make a backup of your solution before making changes (just in case something goes wrong).
  2. In your StylesProject, create a new ResourceDictionary. This will be the dictionary that merges all of your other styles and resources so name it appropriately.
  3. Cut and paste all of your style related resources that you had defined in your App.xaml into your new resource dictionary.
  4. In your WpfApplication project, reference your new resource dictionary in your App.xaml file. Your application should now look like it did before you started making changes.
  5. In your CustomControls project, create a new ResourceDictionary named DesignTimeResources.xaml under the Properties folder.
  6. Build your solution. Note: you really only have to build the CustomControls project at this point in time.
  7. You now have to edit the CustomControls csproj. Note: you may have to unload the project to do it from Visual Studio.
  8. In CustomControls.csproj, search for DesignTimeResources.xaml. You should find a block that looks like the following:
<Page Include="Properties\DesignTimeResources.xaml">
    <SubType>Designer</SubType>
    <Generator>MSBuild:Compile</Generator>
</Page>
  1. Replace the block from Step 8 with the following:
<Page Include="Properties\DesignTimeResources.xaml" Condition="'$(DesignTime)'=='true' OR ('$(SolutionPath)'!='' AND Exists('$(SolutionPath)') AND '$(BuildingInsideVisualStudio)'!='true' AND '$(BuildingInsideExpressionBlend)'!='true')">
    <Generator>MSBuild:Compile</Generator>
    <SubType>Designer</SubType>
    <ContainsDesignTimeResources>true</ContainsDesignTimeResources>
</Page>
  1. Now reload/build the CustomControls project.
  2. Add a reference to the ResourceDictionary from your StylesProject to the DesignTimeResources.xaml file you just created.
  3. Rebuild your solution.

You should now see the your styling in the designer of your CustomControls project!



标签: c# wpf xaml mvvm