dotnet/wpf · error · InvalidOperationException
SR.Format(SR.PropertyMustHaveValue, "DataType"…
Error message
SR.Format(SR.PropertyMustHaveValue, "DataType", this.GetType().Name)
What it means
TemplateKey implements ISupportInitialize; EndInit validates that the DataType property was set during the initialization block. If BeginInit was called but DataType was never assigned, EndInit throws InvalidOperationException because a template key without a DataType cannot be used to look up implicit templates.
Solutions
- Set the DataType property (a Type or string) after BeginInit() and before calling EndInit().
- If the key is not meant to be an implicit template key, construct it with the constructor overload that takes a template name instead of using the BeginInit/EndInit pattern.
- Wrap EndInit in a try-catch for InvalidOperationException when the DataType is legitimately absent, and fall back to a named template key.
Example fix
// before var key = new TemplateKey(); key.BeginInit(); key.EndInit(); // throws // after var key = new TemplateKey(); key.BeginInit(); key.DataType = typeof(MyViewModel); key.EndInit();
Defensive patterns
Strategy: validation
Validate before calling
if (key is ISupportInitialize si && key.GetType().GetProperty("DataType")?.GetValue(key) == null)
key.GetType().GetProperty("DataType")?.SetValue(key, typeof(Target));
si?.EndInit(); Try / catch
try { si.EndInit(); }
catch (InvalidOperationException ex) when (ex.Message.Contains("DataType")) { /* substitute named key or log */ } Prevention
- Always pair BeginInit with setting DataType and EndInit in the same scope.
- Prefer constructors that take the required data over the initialization pattern when possible.
- Add an assertion that DataType != null immediately before EndInit.
When it happens
Trigger: Calling BeginInit() on a TemplateKey (or a TemplateNameKey/TypeDataKey subclass) and then EndInit() without ever setting the DataType property in between.
Common situations: Hand-written XAML parser or tooling that creates template keys programmatically and forgets to set DataType before finishing initialization; deserializers that call the initialization pattern but skip optional properties.
Understand the failure class
Background: "missing required argument" and "the following required arguments were not provided": what required-argument errors mean and how to fix them — this error's family across 20 libraries.
Related errors
- SR.EndInitWithoutBeginInitNotSupported
- SR.Illegal_InheritanceBehaviorSettor
- SR.Image_EndInitWithoutBeginInit
- SR.Image_InInitialize
- SR.Image_OnlyOneInit
AI-assisted analysis of dotnet/wpf@81131a70a4 (2026-09-14).
Data as JSON: /api/errors/b9965c69a3b55d24.
Report an issue: GitHub.
Appendix: source
Thrown at src/Microsoft.DotNet.Wpf/src/PresentationFramework/System/Windows/TemplateKey.cs:50
_dataType = dataType;
_templateType = templateType;
}
#region ISupportInitialize
/// <summary>Begin Initialization</summary>
void ISupportInitialize.BeginInit()
{
_initializing = true;
}
/// <summary>End Initialization, verify that internal state is consistent</summary>
void ISupportInitialize.EndInit()
{
if (_dataType == null)
{
throw new InvalidOperationException(SR.Format(SR.PropertyMustHaveValue, "DataType", this.GetType().Name));
}
_initializing = false;
}
#endregion ISupportInitialize
/// <summary>
/// The type for which the template is designed. This is either
/// a Type (for object data), or a string (for XML data). In the latter
/// case the string denotes the XML tag name.
/// </summary>
public object DataType
{
get { return _dataType; }
set
{
if (!_initializing)View on GitHub (pinned to 81131a70a4)