Skip to content

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

@IvanGit

Description

@IvanGit

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!

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions