WPF共享资源字典

yftpprvb  于 2022-12-14  发布在  其他
关注(0)|答案(3)|浏览(207)

我已经使用自定义类在我的WPF应用程序中实现了共享资源功能。这是一个创建和管理字典的示例代码

public class SharedResourceDictionary : ResourceDictionary
{
    /// <summary>
    /// Internal cache of loaded dictionaries 
    /// </summary>
    public static Dictionary<Uri, ResourceDictionary> SharedDictinaries = new Dictionary<Uri, ResourceDictionary>();

    /// <summary>
    /// Local member of the source uri
    /// </summary>
    private Uri _sourceUri;

    private static bool IsInDesignMode
    {
        get
        {
            return (bool)DependencyPropertyDescriptor.FromProperty(DesignerProperties.IsInDesignModeProperty,
                                                                   typeof(DependencyObject)).Metadata.DefaultValue;
        }
    }

    /// <summary>
    /// Gets or sets the uniform resource identifier (URI) to load resources from.
    /// </summary>
    public new Uri Source
    {
        get
        {
            if (IsInDesignMode)
            {
                return base.Source;
            }
            return _sourceUri;
        }
        set
        {
            if (!IsInDesignMode)
            {
                base.Source = value;
                return;
            }
            _sourceUri = value;
            if (!SharedDictinaries.ContainsKey(value))
            {
                base.Source = value;
                SharedDictinaries.Add(value, this);
            }
            else
            {
                MergedDictionaries.Add(SharedDictinaries[value]);
            }
        }
    }
}

这个文件是在一个单独的程序集中实现的,我已经在我的shell WPF应用程序中引用了它。
我在app.xamlint中定义了我的资源,方法如下

<Application.Resources>
    <ResourceDictionary>
        <ResourceDictionary.MergedDictionaries>
            <Infrastructure:SharedResourceDictionary Source="pack://application:,,,/CuratioCMS.Client.Resources;Component/Themes/General/Brushes.xaml" />
            <Infrastructure:SharedResourceDictionary Source="pack://application:,,,/Fluent;Component/Themes/Office2010/Silver.xaml" />
        </ResourceDictionary.MergedDictionaries>
    </ResourceDictionary>
   </Application.Resources>

如果我删除Brushes.xaml,它可以工作,但是当我切换到设计视图时,我得到以下错误
调用的目标引发了异常错误
有人能帮我解决这个问题吗?

eiee3dmh

eiee3dmh1#

为了解决这个问题,我做了(我真的很想在VisualStudio 2010中的设计时工作):

public string SourcePath { get; set; }

public new Uri Source
{
    get
    {
        if (IsInDesignMode)
        {
            return base.Source;
        }
        else
        {
            return _sourceUri;
        }

    }
    set
    {
        if (value == null)
            return;

        if (IsInDesignMode)
        {
            var dict = Application.LoadComponent(new Uri(SourcePath, UriKind.Relative)) as ResourceDictionary;
            MergedDictionaries.Add(dict);
            return;
        }

        _sourceUri = value;
        if (!_sharedDictionaries.ContainsKey(value))
        {
            base.Source = value;

            _sharedDictionaries.Add(value, this);
        }
        else
        { 
            MergedDictionaries.Add(_sharedDictionaries[value]);
        }
    }
}

在我XAML中:

<SharedResourceDictionary SourcePath="JooThemes;component/Buttons/Small/SettingsToggleStyle.xaml" Source="/JooThemes;component/Buttons/Small/SettingsToggleStyle.xaml" />
g6baxovj

g6baxovj2#

我知道这个问题已经解决了,但由于我一直在与一位朋友研究替代解决方案,我想与大家分享一下:
1.在xaml中的任何地方都使用WPF ResourceDictionary,这样Blend和VS设计器就不会中断。
1.参考熔核包Sundew.Xaml.OptimizationsSundew.Xaml.Optimizer
1.在项目的根目录中添加一个sxo-settings.json并启用ResourceDictionaryCachingOptimizer
1.组建
生成将使用缓存/共享ResourceDictionary。
如需详细信息,请参阅:https://github.com/hugener/Sundew.Xaml.Optimizations
和样:https://github.com/hugener/Sundew.Xaml.Optimizer.Sample

9cbw7uwe

9cbw7uwe3#

我在某个地方读到,这是一个内存问题@设计时。我在源代码的设置程序中解决了它:

/// <summary>
/// Gets or sets the uniform resource identifier (URI) to load resources from.
/// </summary>
public new Uri Source
{
    get { return _sourceUri; }
    set
    {
        _sourceUri = value;
        if (!_sharedDictionaries.ContainsKey(value))
        {
            try
            {
                 //If the dictionary is not yet loaded, load it by setting
                 //the source of the base class
                base.Source = value;
            }
            catch (Exception exp)
            {
                //only throw exception @runtime to avoid "Exception has been 
                //thrown by the target of an invocation."-Error@DesignTime
                if( ! IsInDesignMode )
                    throw;
            }
            // add it to the cache
            _sharedDictionaries.Add(value, this); 
        }
        else
        {
            // If the dictionary is already loaded, get it from the cache 
            MergedDictionaries.Add(_sharedDictionaries[value]); 
        }                 
    }
}

相关问题