Загрузка / использование ресурсных словарей из размещенного на WinForms элемента управления WPF - PullRequest
11 голосов
/ 24 февраля 2009

У меня есть приложение Windows Forms, которое должно содержать элемент управления WPF во время выполнения. У меня есть базовый хостинг и взаимодействие завершено (с использованием элемента управления ElementHost), и все работает нормально, пока я не попытаюсь сделать что-то, требующее от элемента управления WPF использования определенных пользовательских словарей ресурсов. (Элемент управления WPF и все его словари ресурсов определены в одной библиотеке DLL элемента управления WPF.)

Как только это происходит, я получаю кучу ошибок, которые выглядят так:

System.Windows.ResourceDictionary Warning: 9 : Resource not found; ResourceKey='DocumentHeaderInterestStyle'

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

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

В управляющей библиотеке WPF есть файл словаря ресурсов с именем «Default.xaml», определенный в проекте со следующими свойствами:

Действие сборки: страница Копировать в выходной каталог: не копировать Пользовательский инструмент: MSBuild: Compile

Автономное приложение WPF имеет следующую запись в своем файле App.xaml:

    <ResourceDictionary x:Uid="ResourceDictionary_1">
        <ResourceDictionary.MergedDictionaries>
            <ResourceDictionary x:Uid="ResourceDictionary_2" Source="/SmartClient.Infrastructure;component/Themes\Default.xaml"/>
        </ResourceDictionary.MergedDictionaries>
    </ResourceDictionary>

Похоже, что управляющая библиотека уже должна знать, как получить свои ресурсы. Использование Resources.MergedDictionaries.Add () похоже, что оно должно работать, но где мне взять экземпляр существующего словаря?

Ответы [ 3 ]

4 голосов
/ 24 февраля 2009

Предполагая, что вы знаете, какие ресурсы вам нужны (звучит так, как вы), вы просто должны быть в состоянии "внедрить" их самостоятельно. Что-то вроде:

var wpfControl = new ...;
wpfControl.Resources.Add(...);
elementHost.Child = wpfControl;

В своем вопросе вы упоминаете, что в управляющей библиотеке есть словари ресурсов. Если это так, вы можете просто сделать это:

var wpfControl = new ...;
wpfControl.Resources.MergedDictionaries.Add(/* instance of existing dictionary */);
elementHost.Child = wpfControl;
2 голосов
/ 21 июля 2009

Для загрузки словарей ресурсов, встроенных в сборку, я использовал следующий фрагмент для загрузки их во время выполнения:

//using System.Windows
ResourceDictionary dict = new ResourceDictionary();
dict.Source = new Uri("MyResourceDictionary.xaml", UriKind.Relative);

Application.Current.Resources.MergedDictionaries.Add(dict);

Это также будет работать для загрузки словаря в исполняемый каталог.

0 голосов
/ 08 сентября 2015

Предположим, что ваши стили / шаблоны / ресурсы разделены на множество файлов Resources1.xaml и Resources2.xaml, вы можете объединить их в один словарь ресурсов (AllResources.xaml). Словарь ресурсов можно легко добавить к элементу управления в файле xaml элемента управления. Смотрите пример ниже.

(!) Установите для Resources1.xaml, Resources2.xaml и AllResources.xaml действия по построению Page

Resources1.xaml

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

    <ControlTemplate x:Key="ScrollViewerControlTemplate" TargetType="{x:Type ScrollViewer}">
        ...
    </ControlTemplate>

    <LinearGradientBrush x:Key="VerticalScrollBarBackground" EndPoint="1,0" StartPoint="0,0">
        ...
    </LinearGradientBrush>

    <Style x:Key="StyleA" TargetType="{x:Type ScrollBar}">
        ...
    </Style>

</ResourceDictionary>

Resources2.xaml

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


    <Style x:Key="StyleB" TargetType="{x:Type ScrollBar}">
        ...
    </Style> 

    <Style x:Key="StyleC" TargetType="{x:Type TextBlock}">
        ...
    </Style>

</ResourceDictionary>

AllResources.xaml

Добавить источники словарей ресурсов как относительные пути в AllResources.xaml

<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation">
    <ResourceDictionary.MergedDictionaries>
        <ResourceDictionary Source="Resources1.xaml" />
        <ResourceDictionary Source="Resources2.xaml" />
    </ResourceDictionary.MergedDictionaries>
</ResourceDictionary>

Наконец-то в вашем UserControl

<UserControl.Resources>
    <ResourceDictionary>
        <ResourceDictionary.MergedDictionaries>
            <ResourceDictionary Source="pack://application:,,,/projectName;component/PathToTheFileRelativeToProjectRootDirectory/AllResources.xaml
        <converters:StringToUpperCaseConverter x:Key="StringToUpperCaseConverter" />
        <converters:LocalizationEntryToStringCaseConverter x:Key="LocalizationEntryToStringCaseConverter" />
    </ResourceDictionary>
</UserControl.Resources>
...