【问题标题】:Styles from generic.xaml are not applied不应用 generic.xaml 中的样式
【发布时间】:2012-06-24 08:06:00
【问题描述】:

我创建了一个类库程序集,在其中创建了自定义控件,并在 generic.xaml 文件中定义了默认样式。

这似乎是一个相当普遍的问题,只要有很多人发布它。 但是我找不到任何有用的答案。

  • generic.xaml 位于 Themes 文件夹中。
  • generix.xaml 文件 Build Action 设置为 Page。
  • ThemeInfo 在我的 AssemblyInfo.cs 中正确定义。

在我的测试应用程序中,如果我手动将自定义控件程序集中的 generic.xaml 文件合并到应用程序 App.xaml 文件中,如下所示:

<Application.Resources>
  <ResourceDictionary>
    <ResourceDictionary.MergedDictionaries>
      <ResourceDictionary Source="/MyControlsAssembly;component/Themes/generic.xaml"/>
    </ResourceDictionary.MergedDictionaries>
  </ResourceDictionary>
</Application.Resources>

然后自定义控件的主题正确,但如果我不手动合并 generic.xaml,这些控件将显示为默认的 Windows 主题。

你能告诉我我忘记了什么和/或做错了什么吗?

附加信息:

  • 我的 ThemeInfo 程序集属性定义如下:

    [assembly: ThemeInfo(ResourceDictionaryLocation.SourceAssembly, ResourceDictionaryLocation.SourceAssembly)]

    (注意:对于 ThemeInfo 属性的参数任意组合,结果都是一样的)

  • 在 Themes 文件夹中的 generic.xaml 文件旁边还有另外两个 .xaml 文件。

  • Themes 文件夹中有一个子文件夹,它本身包含另一个 .xaml 文件。

【问题讨论】:

  • 您的自定义控件的静态构造函数中是否还设置了 DefaultStyleKeyProperty?
  • 运气好能搞定这个吗?我的自定义控件程序集几乎完全相同。如果我在 App.config 中添加对 generic.xaml 文件的引用,则控件是主题的。如果我把它排除在外,我什么也得不到。
  • 此链接是否适用? social.msdn.microsoft.com/Forums/vstudio/en-US/…我也面临同样的问题,我认为这是根本原因
  • 这个问题有什么解决办法吗?我遇到了完全相同的事情,按照此处或blogs.magnatis.com/tim/dude-wheres-my-default-style 中建议的步骤没有帮助。我需要像这篇文章一样在 App.xaml 中包含合并。
  • 在控件库的 AssemblyInfo.cs 中添加 ThemeInfo 对我有用。我用过(无,SourceAssembly)。

标签: wpf styles themes generic.xaml


【解决方案1】:

您的自定义控件构造函数中需要以下行:

public class MyCustomControl : Control
{
    static MyCustomControl()
    {
        DefaultStyleKeyProperty.OverrideMetadata(typeof(MyCustomControl), new FrameworkPropertyMetadata(typeof(MyCustomControl)));
    }
}

如果你在主题文件夹中有一个 generic.xaml 文件,具有以下示例样式:

<Style TargetType="{x:Type local:MyCustomControl}">
    <Setter Property="Template">
        <Setter.Value>
            <ControlTemplate TargetType="{x:Type local:MyCustomControl}">
                <Border>
                    <Label>Testing...</Label>
                </Border>
            </ControlTemplate>
        </Setter.Value>
    </Setter>
</Style>

现在样式将自动应用,无需任何额外的合并。

【讨论】:

  • 这对我不起作用。看看我对最初问题的评论
  • 从一个空白的解决方案开始,看看你是否可以让它从那里开始工作?
  • 这就是我正在做的。我来自 Xceed 数据网格。如果我创建一个新的 MyControl : Control 或 MyButton : Button,它可以工作。也许是 Xceed 主题支持在这里发挥作用,我需要查看他们关于主题的教程,或者只是在我的应用程序中接受合并字典。除非出现其他想法。
【解决方案2】:

为了在我的自定义控件库中应用 Themes\Generic.xaml 中的默认样式,我决定从一个完善的开源控件库 (MahApps) 中寻求灵感。该项目为您提供了一个非常好的示例,说明如何构建和布局自定义控件库。

长话短说,要在 Themes\Generic.xaml 中获取默认样式,您需要在自定义控件库的 AssemblyInfo.cs 文件中包含以下内容:

[assembly: ThemeInfo(ResourceDictionaryLocation.None, ResourceDictionaryLocation.SourceAssembly)]

在我的例子中,我的自定义控件 AssemblyInfo.cs 看起来像:

using System.Runtime.InteropServices;
using System.Windows;
using System.Windows.Markup;

[assembly: AssemblyCopyright("...")]
[assembly: ComVisible(false)]

[assembly: ThemeInfo(ResourceDictionaryLocation.None, ResourceDictionaryLocation.SourceAssembly)]

[assembly: AssemblyVersion("1.0.0.0")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: AssemblyInformationalVersion("1.0.0.0")]
[assembly: AssemblyTitleAttribute("...")]
[assembly: AssemblyDescriptionAttribute("")]
[assembly: AssemblyProductAttribute("...")]
[assembly: AssemblyCompany("...")]

【讨论】:

    【解决方案3】:

    不确定这是否适用于 WPF,但它适用于 Silverlight:

    构造函数:

    public class MyCustomControl : Control
    {
        static MyCustomControl()
        {
            this.Style = (Style)Application.Current.Resources["MyCustomControlStyle"];
        }
    }
    

    风格:

    <Style x:Key="MyCustomControlStyle" TargetType="{local:MyCustomControl}">
        <Setter Property="Template">
            <Setter.Value>
                <ControlTemplate TargetType="{local:MyCustomControl}">
                    <Border>
                        <Label>Testing...</Label>
                    </Border>
                </ControlTemplate>
            </Setter.Value>
        </Setter>
    </Style>
    

    【讨论】:

      【解决方案4】:

      由于自定义控件程序集中的以下属性,我遇到了同样的问题:

      [assembly: NeutralResourcesLanguage("en-US", UltimateResourceFallbackLocation.Satellite)]
      

      UltimateResourceFallbackLocation.Satellite 更改为UltimateResourceFallbackLocation.MainAssembly 或删除第二个参数完全解决了我的问题(如果您不需要定义程序集的中性语言,也可以删除该属性)。

      【讨论】:

        猜你喜欢
        • 2011-04-01
        • 1970-01-01
        • 2010-12-02
        • 2016-10-16
        • 1970-01-01
        • 1970-01-01
        • 2017-05-16
        • 1970-01-01
        • 2015-01-04
        相关资源
        最近更新 更多