Search code examples
c#wpfsilverlightblend

Fail to re-attach behavior to dependency object after detach


I attached behavior (Behavior in Blend SDK) to a UIElement as I generated it in run time. I also had two buttons to trigger Detach() and Attach() - basically to enable or disable the behavior.

The problem is: after I Detach() the behavior, Attach() failed to restore the behavior to the dependency object, which then remained behavior-less:

// Declare the dependency object and behavior at class scope 
MyControl c = new MyControl();
MyBehavior b = new MyBehavior();

// Function that generate UI Controls with behavior attached
b.Attach(c);

// Function that detach behavior from dependency object
b.Detach();

// Function that re-attach behavior to the same object after it has been detached
b.Attach(c); // <-- Do not see the behavior...

Why is the behavior not re-attaching? And is there a solution or work-around to switch on or off a behavior?


Solution

  • It seems the problem is specific of your behavior's logic. In the following test the behavior reattaches without problems:

    public class ColorBehavior : Behavior<Border>
    {
        public Brush OriginalBrush { get; set; }
    
        protected override void OnAttached()
        {
            base.OnAttached();
    
            this.OriginalBrush = this.AssociatedObject.Background;
            this.AssociatedObject.Background = Brushes.CadetBlue;
        }
    
        protected override void OnDetaching()
        {
            base.OnDetaching();
            this.AssociatedObject.Background = this.OriginalBrush;
        }
    }
    
    public partial class MainWindow : Window
    {
        private ColorBehavior behavior = new ColorBehavior();
        private bool isAttached;
    
        public MainWindow()
        {
            InitializeComponent();
        }
    
        private void Button_Click(object sender, RoutedEventArgs e)
        {
            if (!this.isAttached)
            {
                this.behavior.Attach(this.Border);
                this.isAttached = true;
            }
            else
            {
                this.behavior.Detach();
                this.isAttached = false;
            }
        }
    }
    
    <Window x:Class="WpfApplication1.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:i="http://schemas.microsoft.com/expression/2010/interactivity"
        xmlns:local="clr-namespace:WpfApplication1"
        Title="MainWindow"
        Width="525"
        Height="350">
    <Grid>
        <Border x:Name="Border" Background="Red" />
        <Button Width="50"
                Height="20"
                Click="Button_Click"
                Content="Hey" />
    </Grid>