是否可以从UserControl xaml文件在应用程序中添加wpf ResourceDictionary?

时间:2011-04-01 15:07:03

标签: wpf xaml

是否可以从UserControl xaml在应用程序级别添加ResourceDictionary。

即。在UserControl xaml中执行与C#中相同的操作:

if (Application.Current == null) new Application();
Application.Current.Resources.MergedDictionaries.Add(new ResourceDictionary() {...});

1 个答案:

答案 0 :(得分:1)

您可以编写一个ApplicationDictionaryMerger类,接受字典作为其内容,并将其添加到应用程序的MergedDictionaries,例如:

[ContentProperty("Dictionaries")]
public class ApplicationDictionaryMerger
{
    private readonly ObservableCollection<ResourceDictionary> dictionaries = 
        new ObservableCollection<ResourceDictionary>();

    public ApplicationDictionaryMerger()
    {
        this.dictionaries.CollectionChanged += this.DictionariesChanged;
    }

    private void DictionariesChanged(object sender,
                                     NotifyCollectionChangedEventArgs e)
    {
        // Do whatever you deem appropriate here to get the MergedDictionaries
        var applicationDictionaries = 
            Application.Current.Resources.MergedDictionaries;

        // Enhance this switch statement if you require more functionality
        switch (e.Action)
        {
            case NotifyCollectionChangedAction.Add:
                foreach (var dict in e.NewItems)
                {
                    applicationDictionaries.Add((ResourceDictionary)dict);
                }
                break;
        }
    }

    public IList Dictionaries
    {
        get { return this.dictionaries; }
    }
}

唯一的问题是你需要从XAML实例化上述对象。

最初我认为将它添加到XAML中任何控件的Resources部分都没问题,但事实证明XAML加载器没有实例化未使用的资源。所以我提出了另一种解决方法:将对象设置为任何控件的Tag属性的值。

我很想知道是否有更好的方法可以确保ApplicationDictionaryMerger被实例化。

以下是如何使用它:

<Grid>  <!-- can also be any other control -->
    <Grid.Tag>
        <sandbox:ApplicationDictionaryMerger>
            <ResourceDictionary>
                <!-- add all resources you need here -->
            </ResourceDictionary>
            <!-- you can also add more dictionaries here -->
        </sandbox:ApplicationDictionaryMerger>
    </Grid.Tag>
</Grid>