Application.LoadComponent throws exception when loading XAML resource with AttachedProperty inconsistently
- .NET Core Version: 3.0
- Windows version: 2004
- Does the bug reproduce also in WPF for .NET Framework 4.8?: Inconsistently
Problem description: Loading a XAML resource using Application.LoadComponent will, in some situations, throw an exception when the XAML resource contains an AttachedProperty somewhere inside it.
This is a quick summary of how this issue was found and the attempts made to narrow it's source:
-
The issue was first encountered in a F# WPF application while adding a Interaction.Behaviors (from microsoft/XamlBehaviorsWpf) to a custom Control.
-
Upon inquiry to the aforementioned XamlBehaviorsWpf GitHub (here), it was determined that this issue was reproducible in C# and reproducible using a simple dummy attached property.
-
While trying to determine whether this issue was reproducible in both .NET Core 3.0 and .NET Framework 4.8, I found that it may be actually something more subtle causing this exception to be thrown, as it would inconsistently occur between F# and C#, between .NET Core 3.0 and .NET Framework 4.8 and between Interaction.Triggers and a dummy AttachedProperty. These attempts are all included in the repro solution, and I tried to make it easy to understand both the attempt and the result. This is a summary:
-
C# Project, .NET Core 3.0, Dummy AttachedProperty: Fails
-
C# Project, .NET Framework 4.8, Dummy AttachedProperty: Passes
-
F# Project, .NET Core 3.0, Dummy AttachedProperty: Passes
-
F# Project, .NET Framework 4.8, Dummy AttachedProperty: Passes
-
C# Project, .NET Core 3.0, Interactions.Triggers: Passes
-
C# Project, .NET Framework 4.8, Interactions.Triggers: Passes
-
F# Project, .NET Core 3.0, Interactions.Triggers: Fails
-
F# Project, .NET Framework 4.8, Interactions.Triggers: Fails
- This is my personal guess, please be aware I have but little understanding of the inner workings of WPF. I think, as the exception message suggests, that the member created when an AttachedProperty is assigned using DependencyProperty.RegisterAttached in C# is sometimes invisible to Application.LoadComponent, causing the crash. My conclusion is supported by the following:
- All of the dummy AttachedProperties written in F# will not crash, in either .NET Core 3.0 or .NET Framework 4.8.
- A .NET Core 3.0 in C# using the dummy AttachedProperty crashes. (Intriguingly, the .NET 4.8 does not)
- microsoft/XamlBehaviorsWpf is written in C#.
Actual behavior:
System.Windows.Markup.XamlParseException
HResult=0x80131501
Message='Cannot set unknown member '{clr-namespace:ReproAttachedPropertyCore30.CSharp.Fail}DummyAttached.Foo'.' Line number '11' and line position '6'.
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.Load(XamlReader xamlReader, Boolean skipJournaledProperties, Uri baseUri)
at System.Windows.Markup.XamlReader.Load(XamlReader xamlReader, ParserContext parserContext)
at System.Windows.Markup.XamlReader.Load(XmlReader reader, ParserContext parserContext, XamlParseMode parseMode, Boolean useRestrictiveXamlReader, List`1 safeTypes)
at System.Windows.Markup.XamlReader.Load(Stream stream, ParserContext parserContext, Boolean useRestrictiveXamlReader)
at System.Windows.Markup.XamlReader.Load(Stream stream, ParserContext parserContext)
at System.Windows.Application.LoadComponent(Uri resourceLocator, Boolean bSkipJournaledProperties)
at System.Windows.Application.LoadComponent(Uri resourceLocator)
at ReproAttachedPropertyCore30.CSharp.Fail.App.Main(String[] args) in C:\Users\maxim\Downloads\ReproWithBasicProperty\ReproAttachedPropertyCore30.CSharp.Fail\App.cs:line 18
This exception was originally thrown at this call stack:
[External Code]
Inner Exception 1:
XamlObjectWriterException: 'Cannot set unknown member '{clr-namespace:ReproAttachedPropertyCore30.CSharp.Fail}DummyAttached.Foo'.' Line number '11' and line position '6'.
Expected behavior: The resource to be loaded correctly, without throwing exceptions. Minimal repro: ReproWithBasicProperty.zip
Can confirm this is happening in .NET 4.8, consistently when trying to set either Triggers or Behaviors on a DataGrid. I'm wondering if this is caused by the fact that both Triggers and Behaviors (Their properties in Interaction.cs), are private or the fact that the name supplied to them is ShadowTriggers and ShadowBehaviors? I've only just started looking into this as it is a major blocker.
Experiencing similar issues; unable to load class, where my attached property is declared, etc. From the same assembly, as at least one other issue, temporary projects, etc, have supposedly addressed.
At least in my case, I really am loathe to introduce yet another project to salve the issue, which is leading to somewhat of a wide footprint 3P dependencies, albeit somewhat mission critical, i.e. SkiaSharp, SKElement (WPF views), etc, as the error is already in kind of a building block layer to begin with, in the overall solution scheme of things.