在解决方案中跨不同项目访问ResourceDictionary

时间:2013-12-05 12:03:57

标签: c# wpf xaml user-controls

如何从解决方案中的不同项目访问ResourceDictionary

我的解决方案文件包含一些项目。其中一个项目名为“Common”,包含一个名为SharedResource.xaml的资源。

普通中的

SharedResource.xaml

    <ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
                        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
                        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
                        xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 
                        mc:Ignorable="d">
        <ImageBrush x:Key="UserIcon" ImageSource="/Images\icon_user.png"/>
    </ResourceDictionary>

这就是我试图让SharedResource Dictionary在我的一个UserControl中可用的方法。

<UserControl x:Class="MasterDataManagement.View.DisplayMasterDataView"
        xmlns:telerik="http://schemas.telerik.com/2008/xaml/presentation"
        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"
        xmlns:i="http://schemas.microsoft.com/expression/2010/interactivity"
        xmlns:command="http://www.galasoft.ch/mvvmlight"
        xmlns:common="clr-namespace:Common;assembly=Common"
        mc:Ignorable="d"
        d:DesignWidth="800" d:DesignHeight="600" d:DataContext="{Binding DisplayMasterDataViewModel, Source={StaticResource ViewModelLocator}}">

    <UserControl.Resources> 
        <ResourceDictionary> <!-- ERROR Each dictionary entry must have an associated key.-->
            <ResourceDictionary.MergedDictionaries>
                <ResourceDictionary Source="pack://application:,,,/Common;component/Resources/SharedResources.xaml"/>
            </ResourceDictionary.MergedDictionaries>
        </ResourceDictionary>
    </UserControl.Resources>

    <Grid>
    <!-- Removed Content -->
    </Grid>
</UserControl>

不幸的是,这种方法不起作用,我不确定我错过了什么。上面的代码导致此错误消息:每个字典条目必须具有关联的密钥。

有什么想法吗?

注意:

  • 我无法将ResourceDictionary放入App.xaml,因为我创建了直接的UserControl实例(类似于UserControl uc = new DisplayMasterDataView())。
  • 只有“项目”中设置为“启动项目”的App.xaml才会“执行”。我的解决方案由一个MainProject(设置为StartUp Project)和一些其他项目组成,这些项目在MainProject中用作模块。现在,我需要在我的MainProject中使用这个模块,这样做:

    UserControl uc = new DisplayMasterDataView();

我的观点是,从另一个项目创建UserControl的实例不会执行包含UserControl的项目中的App.xaml。因此,我必须使用<UserControl.Resources> </UserControl.Resources>来定义我的资源。 我之前提到过这一点,因为大多数示例项目使用App.xaml来定义资源。

3 个答案:

答案 0 :(得分:3)

  

每个词典条目必须有一个关联的键...

该错误只是告诉您需要使用ResourceDictionary表示法向x:Key添加密钥...在这种情况下,'词典条目'是您的{{1}并且'关联键'是您之后称之为引用它的任何内容,在下面的示例中,“ResourceDictionary”:

CommonResourceDictionary

答案 1 :(得分:0)

我的WinView项目包含一个名为ViewResources.xaml的文件,其中我将控件所需的所有资源放在该项目中。它还链接到同一项目中的其他xaml文件:

<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
                xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"

    <ResourceDictionary.MergedDictionaries>
        <ResourceDictionary Source="MainTabControlStyle.xaml" />        
    </ResourceDictionary.MergedDictionaries>

    <!-- ==================== Data Templates ==================== -->

    <DataTemplate DataType="{x:Type myNameSpace:MyViewModel}">
        <controls:MyUserControl MyProperty="{Binding ...etc...}" />
    </DataTemplate>

</ResourceDictionary>

我的主项目然后在App.xaml中引用它:

    <ResourceDictionary>
        <ResourceDictionary.MergedDictionaries>

            <!-- Main Theme -->
            <ResourceDictionary Source="pack://application:,,,/WPF.Themes;component/BureauBlue/Theme.xaml" />

            <!-- Global Resources for Views -->
            <ResourceDictionary Source="pack://application:,,,/MyProject.WinView;component/ViewResources.xaml" />
            <ResourceDictionary Source="pack://application:,,,/MyProject.WinUI;component/HelpResources.xaml" />

        ... and so on and so forth ...

        </ResourceDictionary.MergedDictionaries>

    </ResourceDictionary>

</Application.Resources>

我不知道这会如何阻止您直接创建UserControl。

答案 2 :(得分:0)

解决方案来了,谢谢你指引我走向正确的方向 Rohit Vats

不工作

<UserControl.Resources>
    <gridView:RadContextMenuXamlHolder x:Key="ContextMenuHolder">
        <telerik:RadContextMenu DataContext="{Binding Path=UIElement.Column.DataControl.DataContext, RelativeSource={RelativeSource Self}}" InheritDataContext="False"
                                StaysOpen="True" x:Name="CellCellContextMenu" Placement="Bottom" Loaded="ContextMenu_OnLoaded">
            <telerik:RadMenuItem x:Name="ColumnsMenuEntry" Header="Choose Columns:" ItemsSource="{Binding Path=Menu.UIElement.Column.DataControl.Columns, RelativeSource={RelativeSource Self}}" StaysOpenOnClick="True">
                <telerik:RadMenuItem.ItemContainerStyle>
                    <Style TargetType="telerik:RadMenuItem">
                        <Setter Property="Header" Value="{Binding Header}" />
                        <Setter Property="IsChecked" Value="{Binding IsVisible, Mode=TwoWay}" />
                        <Setter Property="IsCheckable" Value="True" />
                    </Style>
                </telerik:RadMenuItem.ItemContainerStyle>
            </telerik:RadMenuItem>
            <telerik:RadMenuItem Header="Show all columns" Click="RadMenuItem_ShowAllColumns_OnClick"/>
            <telerik:RadMenuItem Header="Hide all columns" Click="RadMenuItem_HideAllColumns_OnClick"/>
        </telerik:RadContextMenu>
    </gridView:RadContextMenuXamlHolder>

    <Style TargetType="telerik:GridViewHeaderCell">
        <Setter Property="telerik:RadContextMenu.ContextMenu" Value="{Binding Path=CellContextMenu, Source={StaticResource ContextMenuHolder}}"/>
    </Style>

    <ResourceDictionary>
        <ResourceDictionary.MergedDictionaries>
            <ResourceDictionary Source="pack://application:,,,/Common;component/SharedResources.xaml"/>
        </ResourceDictionary.MergedDictionaries>
    </ResourceDictionary>
</UserControl.Resources>

<强>工作

<UserControl.Resources>
    <ResourceDictionary>
        <gridView:RadContextMenuXamlHolder x:Key="ContextMenuHolder">
            <telerik:RadContextMenu DataContext="{Binding Path=UIElement.Column.DataControl.DataContext, RelativeSource={RelativeSource Self}}" InheritDataContext="False"
                                StaysOpen="True" x:Name="CellCellContextMenu" Placement="Bottom" Loaded="ContextMenu_OnLoaded">
                <telerik:RadMenuItem x:Name="ColumnsMenuEntry" Header="Choose Columns:" ItemsSource="{Binding Path=Menu.UIElement.Column.DataControl.Columns, RelativeSource={RelativeSource Self}}" StaysOpenOnClick="True">
                    <telerik:RadMenuItem.ItemContainerStyle>
                        <Style TargetType="telerik:RadMenuItem">
                            <Setter Property="Header" Value="{Binding Header}" />
                            <Setter Property="IsChecked" Value="{Binding IsVisible, Mode=TwoWay}" />
                            <Setter Property="IsCheckable" Value="True" />
                        </Style>
                    </telerik:RadMenuItem.ItemContainerStyle>
                </telerik:RadMenuItem>
                <telerik:RadMenuItem Header="Show all columns" Click="RadMenuItem_ShowAllColumns_OnClick"/>
                <telerik:RadMenuItem Header="Hide all columns" Click="RadMenuItem_HideAllColumns_OnClick"/>
            </telerik:RadContextMenu>
        </gridView:RadContextMenuXamlHolder>

        <Style TargetType="telerik:GridViewHeaderCell">
            <Setter Property="telerik:RadContextMenu.ContextMenu" Value="{Binding Path=CellContextMenu, Source={StaticResource ContextMenuHolder}}"/>
        </Style>

        <ResourceDictionary.MergedDictionaries>
            <ResourceDictionary Source="pack://application:,,,/Common;component/SharedResources.xaml"/>
        </ResourceDictionary.MergedDictionaries>
    </ResourceDictionary>
</UserControl.Resources>

诀窍是将所有资源转移到<ResourceDictionary> </ResourceDictionary>标记。