XAML - MergedDictionaries выбрасывают исключение XmlParseException «элемент уже добавлен». Зачем? - PullRequest
6 голосов
/ 11 января 2010

У меня следующая, очень легко воспроизводимая проблема: Я создаю приложение xaml, которое использует ресурсы из другого файла. Для этого нужно создать тег MergedDictionaries для объединения локальных и глобальных ресурсов, например:

<Window>
<Window.Resources>
    <ResourceDictionary>
        <ResourceDictionary.MergedDictionaries>
            <ResourceDictionary Source="path.to.xaml.file"/>
            <ResourceDictionary>
                <Style TargetType="{x:Type Border}" x:Key="TypeBlock">

                </Style>
                <Style TargetType="{x:Type Border}" x:Key="SetBlock">

                </Style>
            </ResourceDictionary>
        </ResourceDictionary.MergedDictionaries>
    </ResourceDictionary>
</Window.Resources>
....
</Window>

Этот маленький кусочек кода вылетит, если вы запустите его:

Item has already been added. Key in dictionary: 'System.Windows.Controls.Border'  Key being added: 'System.Windows.Controls.Border'

Если мы удалим тег MergedDictionaries, код будет работать так, как и ожидалось:

<Window>
<Window.Resources>
    <Style TargetType="{x:Type Border}" x:Key="TypeBlock">

    </Style>
    <Style TargetType="{x:Type Border}" x:Key="SetBlock">

    </Style>
</Window.Resources>
</Window>

Я не понимаю, почему возникает исключение, когда мы используем объединенные ресурсы. Конечно, исправить это пока достаточно просто (переместите ресурсы на более низкий уровень). Было бы неплохо узнать, является ли это "нормальным" поведением ...

1 Ответ

10 голосов
/ 11 января 2010

Если ваши ресурсы не находятся в отдельном файле, то они не должны быть частью объединенных словарей. Переместите их наружу так:

<Window.Resources>
    <ResourceDictionary>
        <ResourceDictionary.MergedDictionaries>
            <ResourceDictionary Source="path.to.xaml.file"/>
        </ResourceDictionary.MergedDictionaries>

        <Style TargetType="{x:Type Border}" x:Key="TypeBlock">

        </Style>
        <Style TargetType="{x:Type Border}" x:Key="SetBlock">

        </Style>
    </ResourceDictionary>
</Window.Resources>

При этом сообщение об ошибке немного вводит в заблуждение и может быть результатом ошибки в компиляторе XAML.

...