dotnet/wpf · error · InvalidOperationException
SR.Format(SR.PropertyIsInitializeOnly, "DataType"…
Error message
SR.Format(SR.PropertyIsInitializeOnly, "DataType", this.GetType().Name)
What it means
The DataType property of TemplateKey is write-once and only during the initialization window. If a setter is invoked outside of the BeginInit/EndInit pair, or DataType is set to a different value after it was already assigned, the property setter throws InvalidOperationException. This guarantees template keys are immutable once committed.
Solutions
- Call BeginInit() before assigning DataType and EndInit() afterwards.
- Create a new TemplateKey instance instead of mutating DataType on an existing one.
- If a different type is needed, construct a fresh key with the desired DataType in the constructor-supported flow.
Example fix
// before var key = new TemplateKey(); key.DataType = typeof(Customer); // throws: not initializing // after var key = new TemplateKey(); key.BeginInit(); key.DataType = typeof(Customer); key.EndInit();
Defensive patterns
Strategy: validation
Validate before calling
if (key.DataType != null)
throw new InvalidOperationException("TemplateKey.DataType already set; create a new key."); Try / catch
try { key.DataType = value; }
catch (InvalidOperationException) { key = CreateNewKey(value); } Prevention
- Treat TemplateKey as immutable after EndInit.
- Always wrap DataType assignment in BeginInit/EndInit.
- Never reuse key instances across different types.
When it happens
Trigger: Setting TemplateKey.DataType directly without calling BeginInit() first; setting DataType again (to a different value) after it was already assigned even inside an initialization block.
Common situations: Developer treats DataType like a normal mutable property; tooling that reuses and reconfigures a TemplateKey instance for a second template; data-binding attempts that try to assign DataType after creation.
Understand the failure class
Background: "Invalid state transition" errors: "status must be X, actually Y", "already rejected/charging/uninstalled", "cannot ... while running" — what they mean when a library rejects your call — this error's family across 31 libraries.
Related errors
- SR.PropertyIsInitializeOnly (formatted with "Prefix", type…
- SR.PropertyIsInitializeOnly (formatted with "Uri", type…
- Can't Assign to Known Member attributes
- Cannot initialize compressor.
- CannotChangeAfterSealed
AI-assisted analysis of dotnet/wpf@81131a70a4 (2026-09-14).
Data as JSON: /api/errors/8ee3141ede0c73a6.
Report an issue: GitHub.
Appendix: source
Thrown at src/Microsoft.DotNet.Wpf/src/PresentationFramework/System/Windows/TemplateKey.cs:69
}
_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)
throw new InvalidOperationException(SR.Format(SR.PropertyIsInitializeOnly, "DataType", this.GetType().Name));
if (_dataType != null && value != _dataType)
throw new InvalidOperationException(SR.Format(SR.PropertyIsImmutable, "DataType", this.GetType().Name));
Exception ex = ValidateDataType(value, "value");
if (ex != null)
throw ex;
_dataType = value;
}
}
/// <summary> Override of Object.GetHashCode() </summary>
public override int GetHashCode()
{
// note that the hash code can change, but only during intialization
// and only once (DataType can only be changed once, from null to
// non-null, and that can only happen during [Begin/End]Init).
// Technically this is still a violation of the "constant duringView on GitHub (pinned to 81131a70a4)