dotnet / dotnet/wpf

Key of Style ignored if given after TargetType in MergedDictionary

Open
#3,399 0 comments 0 reactions 0 assignees View on GitHub
Dominant language
C#
Stars
7.7k
Forks
1.3k
Avg merge
1d 11h
Merged PRs (30d)
61

Description

* .NET Core Version: 3.1.401
* Windows version: Windows 10 Enterprise Version 1903 (OS Build 18362.1016)
* Does the bug reproduce also in WPF for .NET Framework 4.8?: Yes

**Problem description:**

When a `Style` is in a merged dictionary and `TargetType` comes before `x:Key`, then `x:Key` is ignored and `TargetType` is used as the value of `x:Key`.

In a brand new WPF application, put the following into `MainWindow.xaml`.

```XAML






<Style TargetType="Button" x:Key="Key2"/>
</ResourceDictionary>
</ResourceDictionary.MergedDictionaries>
</ResourceDictionary>
</Window.Resources>
<Grid/>
</Window>
```

Then run the application.

**Expected behavior:**

Initializing the application does _not_ throw an exception.

**Actual behavior:**

Initializing the application _does_ throw an exception. This one.

```
System.Windows.Markup.XamlParseException
HResult=0x80131501
Message='Set property 'System.Windows.ResourceDictionary.DeferrableContent' threw an exception.' Line number '10' and line position '11'.
Source=PresentationFramework
StackTrace:
at System.Windows.Markup.XamlReader.RewrapException(Exception e, IXamlLineInfo lineInfo, Uri baseUri)
at System.Windows.Markup.WpfXamlLoader.Load(XamlReader xamlReader, IXamlObjectWriterFactory writerFactory, Boolean skipJournaledProperties, Object rootObject, XamlObjectWriterSettings settings, Uri baseUri)
at System.Windows.Markup.WpfXamlLoader.LoadBaml(XamlReader xamlReader, Boolean skipJournaledProperties, Object rootObject, XamlAccessLevel accessLevel, Uri baseUri)
at System.Windows.Markup.XamlReader.LoadBaml(Stream stream, ParserContext parserContext, Object parent, Boolean closeStream)
at WpfApp2.MainWindow.InitializeComponent() in C:\Users\twilliams\source\repos\Temp\WpfApp2\MainWindow.xaml:line 1

This exception was originally thrown at this call stack:
[External Code]

Inner Exception 1:
ArgumentException: Item has already been added. Key in dictionary: 'System.Windows.Controls.Button' Key being added: 'System.Windows.Controls.Button'
```

The inner exception contains useful information. It says that `System.Windows.Controls.Button` is being used twice as a key to a dictionary.

**Workarounds:**

I know of two workarounds. First, specify the keys before the target types, like this.
```XAML
<Window x:Class="WpfApp2.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
<Window.Resources>
<ResourceDictionary>
<ResourceDictionary.MergedDictionaries>
<ResourceDictionary>
<Style x:Key="Key1" TargetType="Button"/>
<Style x:Key="Key2" TargetType="Button"/>
</ResourceDictionary>
</ResourceDictionary.MergedDictionaries>
</ResourceDictionary>
</Window.Resources>
<Grid/>
</Window>
```

Second, don't use a merged dictionary, like this.
```XAML
<Window x:Class="WpfApp2.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
<Window.Resources>
<ResourceDictionary>
<Style TargetType="Button" x:Key="Key1"/>
<Style TargetType="Button" x:Key="Key2"/>
</ResourceDictionary>
</Window.Resources>
<Grid/>
</Window>
```

**Minimal repro:**
[ZIP of solution](https://github.com/dotnet/wpf/files/5139583/MWE.zip)

Contributor guide

Open the contributing guide

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.