首页 文章

WPF类库中的程序集范围/根级别样式

提问于
浏览
47

我有一个支持WPF的C#(2008 / .NET 3.5)类库程序集(基于this article) .
我've created several windows, and am now attempting to create a common style set for them. However, as it'是一个类库(而不是WPF应用程序),我没有app.xaml(及其包含的Application和相应的Application.Resources),用于存储这些样式以进行全局访问 .

So: 如何创建一个顶级的样式定义集,这些样式定义将被程序集中的所有xaml文件看到,因为我没有app.xaml(见上文)?和/或是否可以将一个有效的app.xaml添加到类库中?

仅供参考,我尝试在ResourceDictionary.xaml文件中创建ResourceDictionary,并将其包含在"Window.Resources"块中的每个窗口中 . 结果是解决了按钮等的样式......但不适用于封闭的Window . 我可以把 Style="{StaticResource MyWindowStyle}" 放在Window 's opening block, and it compiles and shows up in the VS Design window fine, but during actual runtime I get a parse exception (MyWindowStyle could not be found; I'中,猜测Visual Studio会看到包含在相关行之后的字典,但是CRL会按顺序执行,因此还没有加载ResourceDictionary) .


感谢您的想法,但仍然没有...显然类库不会隐式支持generic.xaml用法 . 我将generic.xaml添加到我的类库项目中,并将其Build Action设置为“Resource” . 它包含:

<ResourceDictionary 
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
    <Style TargetType="{x:Type Window}" x:Key="MyWindow">
        <Setter Property="Background" Value="Black"/>
    </Style>
</ResourceDictionary>

我想要使用主题的窗口xaml如下所示:

<Window x:Class="MyAssembly.ConfigureGenericButtons"
    x:ClassModifier="internal"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    Style="{StaticResource MyWindow}"
    Title="ConfigureGenericButtons">
...Buttons, etc...
</Window>

虽然VS Design窗口没有显示使用MyWindow样式的窗口(即黑色背景),但它编译良好并启动 . 但是,当包含此类库的应用程序进行调用以导致显示此窗口时,我会收到XamlParseException:

找不到名为“”的资源 .

我也尝试省略Style参数,以查看默认情况下窗口是否会使用该样式(我尝试使用包含和不包含的generic.xaml中的x:Key) . 没有错误,但generic.xaml中定义的任何内容都没有出现 .

我在这里做错了什么,或者关于如何允许在窗口上使用常见自定义样式的任何其他想法(即,不必在每个Window的xaml中定义样式) - 需要注意的是这不是应用?

6 回答

  • 0

    如果你没有app.xaml,你仍然可以将它加载到appplication级别的资源中,但是你必须编写代码(而不是xaml)来执行它,类似于这个...

    void LoadIt()
    {
         ResourceDictionary MyResourceDictionary = new ResourceDictionary();
         MyResourceDictionary.Source = new Uri("MyResources.xaml", UriKind.Relative);
         App.Current.Resources.MergedDictionaries.Add(  MyResourceDictionary )
    }
    

    看看这个网站的一个例子:http://ascendedguard.com/2007/08/one-of-nice-features-about-wpf-is-how.html

  • 0

    尝试添加

    Style={DynamicResource MyStyle}
    

    在这种情况下,您不能使用StaticResource .

  • 13

    这听起来像是主题的工作 .

    • /themes/generic.xaml ResourceDictionary添加到项目中 .

    • 将以下内容添加到AssemblyInfo.cs: [assembly: ThemeInfo(ResourceDictionaryLocation.None, ResourceDictionaryLocation.SourceAssembly)]

    • 利润!

    您添加到generic中的所有资源都将被所有控件使用 . 您还可以通过在 themes 目录中包含具有正确主题名称的ResourceDictionary文件来制作配置文件特定主题(Luna,Aero等) .

    下面是更多信息的链接:Create and apply custom themes

  • 3

    WPF博士(或以前称为WPF博士的人)在这个问题上有一个很好的post .

    以下是他们创建Application对象并添加资源的帖子的摘录:

    if (Application.Current == null)
    {
        // create the Application object
        new Application();
    
        // merge in your application resources
        Application.Current.Resources.MergedDictionaries.Add(
            Application.LoadComponent(
                new Uri("MyLibrary;component/Resources/MyResourceDictionary.xaml",
                UriKind.Relative)) as ResourceDictionary);
    }
    

    由于我的程序集是通过interop托管的,我必须添加设置ShutdownMode如下并在完成时关闭:

    new Application() { ShutdownMode = ShutdownMode.OnExplicitShutdown };
    

    它就像一个魅力 .

  • 1

    如果在Window.Resource中加载它,则该字典仅适用于该窗口的子项 . 您需要为窗口及其子项提供它 .

    尝试将其加载到app.xaml文件中 . 这应该使它成为应用程序级资源,而不是窗口级资源 .

  • 13

    所以在花了很多时间之后我终于弄明白了 . 这是如何做:

    • 在WPF控件库中,添加名为 themes 的新文件夹 .

    • themes 文件夹中,添加名为 generic.xaml 的资源字典 .

    • generic.xaml 内,使用以下语法添加资源:

    <SolidColorBrush x:Key="{ComponentResourceKey {x:Type local:UserControl1}, MyEllipseBrush}" Color="Blue" />
    
    • 在您的控件中,使用以下语法访问此资源:
    Background="{StaticResource {ComponentResourceKey {x:Type local:UserControl1}, MyEllipseBrush}}"
    

    注意事项:

    • 当您创建新的WPF控件库时,Visual Studio通常会自动为您完成步骤1和2 .

    • 我不完全理解 ComponentResourceKey 的第一个参数的用途,但它是必需的 . 使用将使用此资源的控件的名称 .

    • Visual Studio 's designer was not be able to locate the resource in my case. It could be a cache issue, I'我不确定 . 但在运行时它可以很好地工作 .

    • 您可以在this MSDN article中阅读有关此语法的更多详细信息 .

    希望这会让生活更轻松 .

相关问题