wpf: System.Drawing.Color can't convert from string in XAML (regression)
- .NET Core Version: 3.1 Preview1 and 3.0 final
- Windows version: 1809
- Does the bug reproduce also in WPF for .NET Framework 4.8?: No
- Is this bug related specifically to tooling in Visual Studio (e.g. XAML Designer, Code editing, etc…)? No
Problem description:
When trying to set a property in XAML that is of type System.Drawing.Color
, the application fails to convert the XAML.
Actual behavior:
Exception:
System.Windows.Markup.XamlParseException: ''Set property 'WpfApp3.MyModel.Color' threw an exception.' Line number '10' and line position '10'.
Stacktrace:
PresentationFramework.dll!System.Windows.Markup.XamlReader.RewrapException(System.Exception e, System.Xaml.IXamlLineInfo lineInfo, System.Uri baseUri) Unknown
PresentationFramework.dll!System.Windows.Markup.WpfXamlLoader.Load(System.Xaml.XamlReader xamlReader, System.Xaml.IXamlObjectWriterFactory writerFactory, bool skipJournaledProperties, object rootObject, System.Xaml.XamlObjectWriterSettings settings, System.Uri baseUri) Unknown
PresentationFramework.dll!System.Windows.Markup.WpfXamlLoader.LoadBaml(System.Xaml.XamlReader xamlReader, bool skipJournaledProperties, object rootObject, System.Xaml.Permissions.XamlAccessLevel accessLevel, System.Uri baseUri) Unknown
PresentationFramework.dll!System.Windows.Markup.XamlReader.LoadBaml(System.IO.Stream stream, System.Windows.Markup.ParserContext parserContext, object parent, bool closeStream) Unknown
PresentationFramework.dll!System.Windows.Application.LoadComponent(object component, System.Uri resourceLocator) Unknown
> WpfApp3.dll!WpfApp3.MainWindow.InitializeComponent() Line 1 C#
WpfApp3.dll!WpfApp3.MainWindow.MainWindow() Line 25 C#
[Native to Managed Transition]
[Managed to Native Transition]
System.Private.CoreLib.dll!System.RuntimeType.CreateInstanceDefaultCtorSlow(bool publicOnly, bool wrapExceptions, bool fillCache) Line 4075 C#
System.Private.CoreLib.dll!System.Activator.CreateInstance(System.Type type, bool nonPublic, bool wrapExceptions) Line 93 C#
System.Private.CoreLib.dll!System.RuntimeType.CreateInstanceImpl(System.Reflection.BindingFlags bindingAttr, System.Reflection.Binder binder, object[] args, System.Globalization.CultureInfo culture) Line 4013 C#
System.Private.CoreLib.dll!System.Activator.CreateInstance(System.Type type, System.Reflection.BindingFlags bindingAttr, System.Reflection.Binder binder, object[] args, System.Globalization.CultureInfo culture, object[] activationAttributes) Line 34 C#
System.Xaml.dll!System.Xaml.Schema.SafeReflectionInvoker.CreateInstanceCritical(System.Type type, object[] arguments) Unknown
System.Xaml.dll!System.Xaml.Schema.XamlTypeInvoker.CreateInstance(object[] arguments) Unknown
System.Xaml.dll!MS.Internal.Xaml.Runtime.ClrObjectRuntime.CreateInstanceWithCtor(System.Xaml.XamlType xamlType, object[] args) Unknown
System.Xaml.dll!MS.Internal.Xaml.Runtime.ClrObjectRuntime.CreateInstance(System.Xaml.XamlType xamlType, object[] args) Unknown
System.Xaml.dll!MS.Internal.Xaml.Runtime.PartialTrustTolerantRuntime.CreateInstance(System.Xaml.XamlType xamlType, object[] args) Unknown
System.Xaml.dll!System.Xaml.XamlObjectWriter.Logic_CreateAndAssignToParentStart(MS.Internal.Xaml.Context.ObjectWriterContext ctx) Unknown
System.Xaml.dll!System.Xaml.XamlObjectWriter.WriteStartMember(System.Xaml.XamlMember property) Unknown
System.Xaml.dll!System.Xaml.XamlWriter.WriteNode(System.Xaml.XamlReader reader) Unknown
PresentationFramework.dll!System.Windows.Markup.WpfXamlLoader.TransformNodes(System.Xaml.XamlReader xamlReader, System.Xaml.XamlObjectWriter xamlWriter, bool onlyLoadOneNode, bool skipJournaledProperties, bool shouldPassLineNumberInfo, System.Xaml.IXamlLineInfo xamlLineInfo, System.Xaml.IXamlLineInfoConsumer xamlLineInfoConsumer, MS.Internal.Xaml.Context.XamlContextStack<System.Windows.Markup.WpfXamlFrame> stack, System.Windows.Markup.IStyleConnector styleConnector) Unknown
PresentationFramework.dll!System.Windows.Markup.WpfXamlLoader.Load(System.Xaml.XamlReader xamlReader, System.Xaml.IXamlObjectWriterFactory writerFactory, bool skipJournaledProperties, object rootObject, System.Xaml.XamlObjectWriterSettings settings, System.Uri baseUri) Unknown
PresentationFramework.dll!System.Windows.Markup.WpfXamlLoader.LoadBaml(System.Xaml.XamlReader xamlReader, bool skipJournaledProperties, object rootObject, System.Xaml.Permissions.XamlAccessLevel accessLevel, System.Uri baseUri) Unknown
PresentationFramework.dll!System.Windows.Markup.XamlReader.LoadBaml(System.IO.Stream stream, System.Windows.Markup.ParserContext parserContext, object parent, bool closeStream) Unknown
PresentationFramework.dll!System.Windows.Application.LoadBamlStreamWithSyncInfo(System.IO.Stream stream, System.Windows.Markup.ParserContext pc) Unknown
PresentationFramework.dll!System.Windows.Application.LoadComponent(System.Uri resourceLocator, bool bSkipJournaledProperties) Unknown
PresentationFramework.dll!System.Windows.Application.DoStartup() Unknown
PresentationFramework.dll!System.Windows.Application..ctor.AnonymousMethod__1_0(object unused) Unknown
WindowsBase.dll!System.Windows.Threading.ExceptionWrapper.InternalRealCall(System.Delegate callback, object args, int numArgs) Unknown
WindowsBase.dll!System.Windows.Threading.ExceptionWrapper.TryCatchWhen(object source, System.Delegate callback, object args, int numArgs, System.Delegate catchHandler) Unknown
WindowsBase.dll!System.Windows.Threading.DispatcherOperation.InvokeImpl() Unknown
WindowsBase.dll!System.Windows.Threading.DispatcherOperation.InvokeInSecurityContext(object state) Unknown
WindowsBase.dll!MS.Internal.CulturePreservingExecutionContext.CallbackWrapper(object obj) Unknown
System.Private.CoreLib.dll!System.Threading.ExecutionContext.RunInternal(System.Threading.ExecutionContext executionContext, System.Threading.ContextCallback callback, object state) Line 172 C#
System.Private.CoreLib.dll!System.Threading.ExecutionContext.Run(System.Threading.ExecutionContext executionContext, System.Threading.ContextCallback callback, object state) Line 132 C#
WindowsBase.dll!MS.Internal.CulturePreservingExecutionContext.Run(MS.Internal.CulturePreservingExecutionContext executionContext, System.Threading.ContextCallback callback, object state) Unknown
WindowsBase.dll!System.Windows.Threading.DispatcherOperation.Invoke() Unknown
WindowsBase.dll!System.Windows.Threading.Dispatcher.ProcessQueue() Unknown
WindowsBase.dll!System.Windows.Threading.Dispatcher.WndProcHook(System.IntPtr hwnd, int msg, System.IntPtr wParam, System.IntPtr lParam, ref bool handled) Unknown
WindowsBase.dll!MS.Win32.HwndWrapper.WndProc(System.IntPtr hwnd, int msg, System.IntPtr wParam, System.IntPtr lParam, ref bool handled) Unknown
WindowsBase.dll!MS.Win32.HwndSubclass.DispatcherCallbackOperation(object o) Unknown
WindowsBase.dll!System.Windows.Threading.ExceptionWrapper.InternalRealCall(System.Delegate callback, object args, int numArgs) Unknown
WindowsBase.dll!System.Windows.Threading.ExceptionWrapper.TryCatchWhen(object source, System.Delegate callback, object args, int numArgs, System.Delegate catchHandler) Unknown
WindowsBase.dll!System.Windows.Threading.Dispatcher.LegacyInvokeImpl(System.Windows.Threading.DispatcherPriority priority, System.TimeSpan timeout, System.Delegate method, object args, int numArgs) Unknown
WindowsBase.dll!MS.Win32.HwndSubclass.SubclassWndProc(System.IntPtr hwnd, int msg, System.IntPtr wParam, System.IntPtr lParam) Unknown
[Native to Managed Transition]
[Managed to Native Transition]
WindowsBase.dll!System.Windows.Threading.Dispatcher.PushFrameImpl(System.Windows.Threading.DispatcherFrame frame) Unknown
WindowsBase.dll!System.Windows.Threading.Dispatcher.PushFrame(System.Windows.Threading.DispatcherFrame frame) Unknown
WindowsBase.dll!System.Windows.Threading.Dispatcher.Run() Unknown
PresentationFramework.dll!System.Windows.Application.RunDispatcher(object ignore) Unknown
PresentationFramework.dll!System.Windows.Application.RunInternal(System.Windows.Window window) Unknown
PresentationFramework.dll!System.Windows.Application.Run() Unknown
WpfApp3.dll!WpfApp3.App.Main() Unknown
Expected behavior: Color gets parsed as in .NET Framework
Minimal repro:
Sample repro: WpfApp3.zip
Switch target framework to net461
and application runs fine.
Gist: Create this model:
public class MyModel
{
public System.Drawing.Color Color { get; set; }
}
Assign it in XAML:
<Grid x:Name="LayoutRoot">
<Grid.DataContext>
<local:MyModel Color="Red" />
</Grid.DataContext>
</Grid>
About this issue
- Original URL
- State: closed
- Created 5 years ago
- Reactions: 4
- Comments: 21 (21 by maintainers)
@dotMorten In the meantime you can use this as a workaround:
It’s not ideal, but it will tell the XAML parser to use that type converter for that specific property. This is a broader issue than just the
System.Drawing.Color
type and I’ll continue to work on finding a good solution.I thought regressions from .NET Framework was of high priority? It’ll definitely cause some migration issues for my customers. While work-aroundable, I want to ensure there’s a clean simple migration to .NET Core.
I can actually improve this for Color and others in Drawing.Primitives now. See https://github.com/dotnet/corefx/pull/42300. How important is such a fix? It seems somewhat uncommon for folks to use System.Drawing types when working with WPF, and they could use the workaround.
The parser takes different code paths if it doesn’t find a converter called out via a
TypeConverterAttribute
. Relying on a “best fit” converter would be a compat break here. This already breaks some tests where it chooses a CollectionConverter for something derived from Collection. But this is unexpected and other parts of the stack pivot on the presence of a converter.The smallest churn change is to identify a converter that applies directly for the type either via attributes (as before) or ensuring the converter is specific to it. That retains the semantics that we get from looking at the attribute but allows the cases where the attribute is no longer present to succeed.
Anything else I think would have larger implications in both the data binding and xaml parsing stacks.
Color has an intrinsic converter for ColorConverter: https://github.com/dotnet/corefx/blob/18e82cabc1d2cddad8ff07ae96edb7296d9fad9d/src/System.ComponentModel.TypeConverter/src/System/ComponentModel/ReflectTypeDescriptionProvider.cs#L130
Did you try actually getting a converter for color rather than trying to read the attributes yourself? Same is true for any of the intrnsic types. These types live lower in the stack on .NETCore and don’t take a dependency on TypeConverter.