1

我有一个自定义控件,它使用在 app.xaml 中链接的资源字典中的样式。如果我关闭链接并将链接添加到包含控件的页面,它将不起作用。这是为什么?为什么我的控件(一个 dll)需要将样式放在 app.xaml 中,而不仅仅是在包含控件的页面上?

4

2 回答 2

3

为什么我的控件(一个 dll)需要将样式放在 app.xaml 中,而不仅仅是在包含控件的页面上?

自定义控件需要默认样式。此默认样式在构造函数中设置。例如:

public CustomControl()
{
    DefaultStyleKey = typeof(CustomControl);
}

设置后,它会在包含该样式的程序集中查找。如果控件位于应用程序中,则它会在 App.xaml 中查找。如果控件在类库中,它会在必须放置在文件夹“Themes”中的文件 Generic.xaml 中查找。您不需要将样式放置在这些文件中的任何一个中。您可以创建一个包含样式的单独文件,并从 App.xaml 或 Themes/Generic.xaml(基于控件的定义位置)引用它。为此,您在其中一个文件中创建一个 MergedDictionary。如果您的控件是在您的应用程序中定义的,您会这样做

<Application x:Class="MyApp.App"
             xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"       
             xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">

    <!--Application Resources-->
    <Application.Resources>
        <ResourceDictionary>
            <ResourceDictionary.MergedDictionaries>
                <ResourceDictionary Source="Controls/CustomControl.xaml" />
            </ResourceDictionary.MergedDictionaries>
        </ResourceDictionary>
    <Application.Resources>
</Application>

如果您的控件是在类库中定义的,则 Themes/Generic.xaml 应如下所示

<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
                    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
    <ResourceDictionary.MergedDictionaries>
        <ResourceDictionary Source="/My.Custom.Assembly;component/FolderLocationOfXaml/CustomControl.xaml" />
    </ResourceDictionary.MergedDictionaries>
</ResourceDictionary>

无论您的自定义控件放置在何处,xaml 都将始终相同

<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
                    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
                    xmlns:local="clr-namespace:My.Custom.Assembly.Controls">
        <Style TargetType="local:CustomControl">
        <Setter Property="Background" Value="Transparent"/>
        <Setter Property="Template">
            <Setter.Value>
                <ControlTemplate TargetType="local:CustomControl">
                    <Grid>
                        <! -- Other stuff here -->
                    </Grid>
                </ControlTemplate>
            </Setter.Value>
        </Setter>
    </Style>
</ResourceDictionary>

如果未定义此默认样式,则无法确定要覆盖的样式。一旦定义了默认样式,您就可以在您的应用程序或任何其他使用控件的地方更改样式。

于 2012-06-15T15:59:30.547 回答
0

尝试将样式移动到控件中,以验证所有必需的引用都已到位,以便您的控件使用字典中的项目。确保包含您的 UserControl 的项目具有对包含资源字典的项目的引用。验证字典的源路径:

<ResourceDictionary Source="/AssemblyName;component/StylesFolderName/ResourceDictionaryName.xaml" />

于 2012-06-15T15:22:47.017 回答