DevExpress.Mvvm.Free icon indicating copy to clipboard operation
DevExpress.Mvvm.Free copied to clipboard

Interactivity: Cannot find governing FrameworkElement or FrameworkContentElement for target element.

Open IvanGit opened this issue 2 months ago • 0 comments

Hello!

Summary

In certain situations, such as when a behavior template is changed and the behavior is removed, a System.Windows.Data error can occur.

Steps to Reproduce

  1. Attach a behavior to an object with data bindings.
  2. Change the template of the associated object.
  3. Observe the System.Windows.Data Error.

Expected Behavior

Changing the template and detaching the behavior should not result in any errors related to data bindings.

Actual Behavior

An error is thrown:

System.Windows.Data Error: 2 : Cannot find governing FrameworkElement or FrameworkContentElement for target element.

Fix

To prevent this, we need to detach the old behavior and clear all bindings before setting AssociatedObject to null.

Interaction.cs:

static void OnBehaviorsTemplateChanged(DependencyObject d, DependencyPropertyChangedEventArgs e) {
    BehaviorCollection objectBehaviors = GetBehaviors(d);
    IList<Behavior> oldItems = d.GetValue(BehaviorsTemplateItemsProperty) as IList<Behavior>;
    DataTemplate newValue = e.NewValue as DataTemplate;
    if(oldItems != null) {
        foreach(Behavior behavior in oldItems)
                objectBehaviors.Remove(behavior);
    }
    ...
}

Should be modified to:

static void OnBehaviorsTemplateChanged(DependencyObject d, DependencyPropertyChangedEventArgs e) {
    BehaviorCollection objectBehaviors = GetBehaviors(d);
    IList<Behavior> oldItems = d.GetValue(BehaviorsTemplateItemsProperty) as IList<Behavior>;
    DataTemplate newValue = e.NewValue as DataTemplate;
    if(oldItems != null) {
        foreach(Behavior behavior in oldItems) {
            behavior.Detach(); // Detach the behavior before removing it
            objectBehaviors.Remove(behavior);
        }
    }
    ...
}

AttachableObject.cs:

public void Detach() {
    OnDetaching();
    AssociatedObject = null;
    IsAttached = false;
}

Should be modified to:

public void Detach() {
    OnDetaching();
    BindingOperations.ClearAllBindings(this); // Clear all bindings before AssociatedObject is set to null
    AssociatedObject = null;
    IsAttached = false;
}

These changes ensure that the behavior is detached before it is removed, and that all bindings are cleared before the associated object is nullified.

Thanks for taking care of this issue!

IvanGit avatar Dec 05 '25 23:12 IvanGit