WPF SharedResourceDictionary - PullRequest
       3

WPF SharedResourceDictionary

1 голос
/ 03 января 2012

Я использовал собственный класс для реализации функциональности общих ресурсов в своем приложении 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]);
            }
        }
    }
}

этот файл реализован в виде отдельной сборки, и я сделал ссылку на него вмое WPF-приложение оболочки.

Мои ресурсы определены в app.xaml int следующим образом:

    <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, он работает, но с этим условием, когда я переключаюв режиме конструктора я получаю следующую ошибку

Исключение было выдано целью вызова

Может ли кто-нибудь помочь мне выяснить проблему?

Ответы [ 3 ]

3 голосов
/ 04 мая 2012

Я решил эту проблему (я действительно хотел работать во время разработки в 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" />
0 голосов
/ 14 апреля 2019

Я знаю, что эта проблема старая и решена, но, поскольку я работал над альтернативным решением с другом, я хотел поделиться им:
1. Используйте WPF ResourceDictionary везде в xaml, таким образом, Blend иКонструктор VS не ломается.
2. Справочные пакеты nuget Sundew.Xaml.Optimizations и Sundew.Xaml.Optimizer
3. Добавьте файл sxo-settings.json вкорень вашего проекта и включите ResourceDictionaryCachingOptimizer
4. Сборка
Сборка будет использовать кэшируемый / разделяемый ResourceDictionary.

Для получения более подробной информации см .: https://github.com/hugener/Sundew.Xaml.Optimizations
И пример: https://github.com/hugener/Sundew.Xaml.Optimizer.Sample

0 голосов
/ 08 февраля 2012

Я где-то читал, что это проблема памяти @ время разработки. Я решил это в Setter of Source:

    /// <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]); 
            }                 
        }
    }
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...