wpf 使用设计时支持从静态成员获取ResourceDictionary源

lf5gs5x2  于 2022-11-18  发布在  其他
关注(0)|答案(1)|浏览(186)

我的基本目标是在一个dll中包含一个ResourceDictionary,我可以通过ResourceDictionary.MergedDictionaries在另一个WPF项目中使用它。但是我不想通过在引用应用程序的XAML中硬编码URI来引用ResourceDictionary,我想引用一些将提供URI的静态成员。
我有一些简化的代码是“工作”的,但只是在运行时。在设计时,它抛出错误,我没有得到智能感知支持。对于这个简化的例子,一切都在一个程序集(没有单独的dll)。
Dic.xaml(要引用的资源字典):

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

    <SolidColorBrush Color="Blue" x:Key="BlueBrush"/>
</ResourceDictionary>

Foo(保存具有URI的静态成员的模块):
(VB.NET版本)

Public Module Foo
    '[VBTest] is the name of assembly
    Public ReadOnly Property URI As New Uri("pack://application:,,,/VBTest;component/Dic.xaml")
End Module

(C#版本)

public static class Foo
{
    //[VBTest] is the name of assembly
    public static Uri URI { get; } = new Uri("pack://application:,,,/VBTest;component/Dic.xaml");
}

最后,在应用程序中要引用ResourceDictionary的位置:

<Window x:Class="MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:local="clr-namespace:VBTest">

    <Window.Resources>
        <ResourceDictionary>
            <ResourceDictionary.MergedDictionaries>
                <ResourceDictionary Source="{x:Static local:Foo.URI}"/>
            </ResourceDictionary.MergedDictionaries>
        </ResourceDictionary>
    </Window.Resources>

    <Border Width="100" Height="100" Background="{StaticResource BlueBrush}"/>
</Window>

在设计阶段,我会收到两个错误:
XDG0062 An error occurred while finding the resource dictionary "".
XDG0062 The resource "BlueBrush" could not be resolved.
然而,该项目将建立和运行得很好。并将显示预期的蓝色方块。
问题是,我如何才能让它在设计时工作?

ztyzrc3y

ztyzrc3y1#

谢天谢地,我找到了一个简单的变通方法。也许不是最漂亮的,但它很优雅。我从this answer中得到了一个有点相关的问题的灵感。
通过创建我自己的类继承自ResourceDictionary,我可以更好地控制加载行为。这听起来很复杂,但实际上我所要做的就是将Source设置为构造函数的一部分,一切就都正常了。
将以下内容添加到代码文件(Module/static classoutsiteFoo):

Public Class StylesResourceDictionary
    Inherits ResourceDictionary

    Public Sub New()
        MyBase.New()
        Source = URI
    End Sub
End Class

请注意,Source = URI是指问题代码中的Foo.URI
然后XAML文件变为:

<Window x:Class="MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:local="clr-namespace:VBTest">

    <Window.Resources>
        <ResourceDictionary>
            <ResourceDictionary.MergedDictionaries>
                <local:StylesResourceDictionary/>
            </ResourceDictionary.MergedDictionaries>
        </ResourceDictionary>
    </Window.Resources>

    <Border Width="100" Height="100" Background="{StaticResource BlueBrush}"/>
</Window>

而且bam,完全的设计时支持,而无需将URI硬编码到引用应用程序中。ResourceDictionary及其URI的控制现在在dll的域中,并且可以使用专用类以(有点)静态的方式引用。

相关问题