stride3d/stride · error · MissingFieldException

The BehaviorsProperty static field is missing on the class…

Error message

The BehaviorsProperty static field is missing on the class Microsoft.Xaml.Behaviors. This version of the assembly is not supported.

What it means

At startup, DragDropAdornerManager reflects over Microsoft.Xaml.Behaviors' Interaction class to grab its private static BehaviorsProperty field. If reflection returns null, the loaded version of the assembly does not have that private field, so the manager throws MissingFieldException because drag-drop adorner behavior cannot work against this assembly version.

Solutions

  1. Pin Microsoft.Xaml.Behaviors.Wpf to the exact version the Stride editor was built against in packages.config/PackageReference
  2. Check binding redirects in app.config so the expected assembly version is actually loaded
  3. Reflect at startup (in a try/catch or version check) and log typeof(Interaction).Assembly.Location to diagnose which assembly is loaded
  4. If the field was renamed upstream, update the reflection string or reimplement the behavior collection lookup without reflection

Example fix

// before
var behaviorsPropertyFieldInfo = typeof(Interaction).GetField("BehaviorsProperty", BindingFlags.NonPublic | BindingFlags.Static);
if (behaviorsPropertyFieldInfo == null)
    throw new MissingFieldException("...not supported.");
// after
<PackageReference Include="Microsoft.Xaml.Behaviors.Wpf" Version="1.1.31" /> <!-- pinned to supported version -->
Defensive patterns

Strategy: validation

Validate before calling

var field = typeof(Interaction).GetField("BehaviorsProperty", BindingFlags.NonPublic | BindingFlags.Static);
if (field == null) throw new NotSupportedException($"Unsupported Microsoft.Xaml.Behaviors version: {typeof(Interaction).Assembly.FullName}");

Type guard

static bool IsSupportedBehaviorsVersion() => typeof(Interaction).GetField("BehaviorsProperty", BindingFlags.NonPublic | BindingFlags.Static) != null;

Try / catch

try { adornerManager = new DragDropAdornerManager(...); }
catch (MissingFieldException ex) { log.Error("Incompatible Microsoft.Xaml.Behaviors assembly", ex); DisableDragDropAdorners(); }

Prevention

When it happens

Trigger: Constructing DragDropAdornerManager (or first drag-over in the asset editor) when the referenced Microsoft.Xaml.Behaviors assembly version differs from the one the code was written against (renamed/moved private static field).

Common situations: NuGet package upgrade of Microsoft.Xaml.Behaviors.Wpf to a version where internal layout changed; binding to an older/newer assembly at runtime via binding redirects; mixing Stride editor with a different behaviors package.

Related errors


AI-assisted analysis of stride3d/stride@96fad776d2 (2026-09-14). Data as JSON: /api/errors/baddc850516c8f86. Report an issue: GitHub.

Appendix: source

Thrown at sources/editor/Stride.Core.Assets.Editor/View/Behaviors/DragDrop/DragDropAdornerManager.cs:52

        private static InsertAdorner insertAdorner;
        private static AdornerLayer currentLayer;
        private static HighlightBorderAdorner dropTargetAdorner;
        private static AdornerLayer dropTargetLayer;
        private static DisplayDropAdorner dataType;

        private static readonly Dictionary<FrameworkElement, Window> ElementToWindowLookup = new Dictionary<FrameworkElement, Window>();
        private static readonly Dictionary<Window, HashSet<FrameworkElement>> WindowToElementsLookup = new Dictionary<Window, HashSet<FrameworkElement>>();

        static DragDropAdornerManager()
        {
            // We use a timer to deactivate the adorners, because the DragLeave event is broken and unusable.
            // OnDragOver is called constantly (seems to be once per frame) so it is more or less safe to work with timers.
            DragLeaveTimer.Timeout += (s, e) => Deactivate();
            // Interaction.cs via DotPeek: "This property is not exposed publicly. This forces clients to use the GetBehaviors [...] ensuring the collection exists"
            // There is no public way to get the BehaviorCollection only if it exists, without creating it if it does not.
            var behaviorsPropertyFieldInfo = typeof(Interaction).GetField("BehaviorsProperty", BindingFlags.NonPublic | BindingFlags.Static);
            if (behaviorsPropertyFieldInfo == null)
                throw new MissingFieldException("The BehaviorsProperty static field is missing on the class Microsoft.Xaml.Behaviors. This version of the assembly is not supported.");

            BehaviorsProperty = (DependencyProperty)behaviorsPropertyFieldInfo.GetValue(null);
        }

        /// <summary>
        /// Updates the state of the adorner associated to the given <see cref="FrameworkElement"/>.
        /// </summary>
        /// <param name="element">The element that is associated to the adorner to update.</param>
        /// <param name="adornerState">The new state to set.</param>
        internal static void SetAdornerState([NotNull] FrameworkElement element, HighlightAdornerState adornerState)
        {
            var adornerLayer = AdornerLayer.GetAdornerLayer(element);
            if (adornerLayer != null)
            {
                Tuple<AdornerLayer, HighlightBorderAdorner> adorner;
                if (DropAdorners.TryGetValue(element, out adorner))
                    adorner.Item2.State = adornerState;
            }

View on GitHub (pinned to 96fad776d2)