Key of Style ignored if given after TargetType in MergedDictionary
- 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
Assessment
This issue has not been assessed yet.