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

  1. Set the DataType property (a Type or string) after BeginInit() and before calling EndInit().
  2. 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.
  3. 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

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


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)