title: How to enable/disable an attached behavior using a boolean property in the ViewModel
body: <p>The title says what I am attempting to do. Here is what I have:</p>
  
  <p>I am using <a href="http://www.codeproject.com/Articles/404827/Rubberband-Behavior-for-WPF-ListBox" rel="nofollow">this</a> CodeProject contribution to attach a RubberBand behavior to a ListBox, so that I can drag-select using the mouse. I was able to modify it, so that I can disable it during instantiation of the ListBox for when I need the ListBox to be non-interactive and only show items.</p>
  
  <p>The ListBox is embeded in a UserControl and contains a canvas that displays elements and in one section of my program I needed the UserControl to be a non-interactive representation of those elements, whereas in the other I needed it to be interactive. However now, I need to be able to toggle between these two states and unfortunately that does not work with the implementation I have ATM and I do not understand why.</p>
  
  <p>I have bound the attached property 'IsActive', which I added in my modified RubberBand-version (see code below) to the property 'IsEditable' of my UserControl-ViewModel, but for some reason the method 'IsActiveProperty_Changed' does not execute, when 'IsEditable' changes.</p>
  
  <p>This is I am using the behavior and binding to 'IsEditable':</p>
  
  <pre><code>&lt;i:Interaction.Behaviors&gt;
      &lt;behavior:RubberBandBehavior IsActive="{Binding RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type UserControl}}, Path=DataContext.IsEditable}"/&gt;
  &lt;/i:Interaction.Behaviors&gt;
  </code></pre>
  
  <p>I have also tried this, which also does not work:</p>
  
  <pre><code>&lt;behavior:RubberBandBehavior IsActive="{Binding RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type UserControl}}, Path=DataContext.IsEditable, UpdateSourceTrigger=PropertyChanged}"/&gt;
  </code></pre>
  
  <p>To disable the hit-detection of the ListBox, I am also binding to 'IsEditable', which <em>does</em> work fine:</p>
  
  <pre><code>        &lt;ListBox.ItemContainerStyle&gt;
              &lt;Style TargetType="{x:Type ListBoxItem}"&gt;
  
                  &lt;Style.Triggers&gt;
                      &lt;DataTrigger Binding="{Binding RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type UserControl}}, Path=DataContext.IsEditable}" Value="False"&gt;
                          &lt;Setter Property="IsHitTestVisible" Value="False" /&gt;
                          &lt;Setter Property="Focusable" Value="False" /&gt;
                      &lt;/DataTrigger&gt;
                  &lt;/Style.Triggers&gt;
              &lt;/Style&gt;
          &lt;/ListBox.ItemContainerStyle&gt;
  </code></pre>
  
  <p>I therefore suspect, that it has to do with my implementation/modification of RubberBandBehavior, since I am still unexperienced to implementing Attached Properties. I hope somebody can spot my error.</p>
  
  <p>Modified RubberBandBehavior.cs</p>
  
  <pre><code>public class RubberBandBehavior : Behavior&lt;ListBox&gt;
  {
      private RubberBandAdorner band;
      private AdornerLayer adornerLayer;
  
      public static readonly DependencyProperty IsActiveProperty =
          DependencyProperty.Register("IsActive", typeof(bool), typeof(RubberBandBehavior),
          new PropertyMetadata(IsActiveProperty_Changed));
  
      private static void IsActiveProperty_Changed(DependencyObject sender,
          DependencyPropertyChangedEventArgs args)
      {
          RubberBandBehavior rubberBandBehavior = (RubberBandBehavior)sender;
  
          if (args.Property.Name == "IsActive")
          {
              bool newIsActiveValue = (bool)args.NewValue;
              bool oldIsActiveValue = (bool)args.OldValue;
  
              if (newIsActiveValue != oldIsActiveValue)
              {
                  rubberBandBehavior.IsActive = newIsActiveValue;
  
                  if (rubberBandBehavior.AssociatedObject != null)
                  {
                      if (newIsActiveValue == true)
                      {
                          rubberBandBehavior.AttachBehavior();
                      }
                      else
                      {
                          rubberBandBehavior.DetachBehavior();
                      }
                  }
              }
          }
      }
  
      public bool IsActive
      {
          get { return (bool)GetValue(IsActiveProperty); }
          set { SetValue(IsActiveProperty, value); }
      }
  
      protected override void OnAttached()
      {
          AssociatedObject.Loaded += new System.Windows.RoutedEventHandler(AssociatedObject_Loaded);
          base.OnAttached();
      }
  
      void AssociatedObject_Loaded(object sender, System.Windows.RoutedEventArgs e)
      {
          if (IsActive == true)
          {
              AttachBehavior();
          }
      }
  
      protected override void OnDetaching()
      {
          AssociatedObject.Loaded -= new System.Windows.RoutedEventHandler(AssociatedObject_Loaded);
          base.OnDetaching();
      }
  
      private void AttachBehavior()
      {
          band = new RubberBandAdorner(AssociatedObject);
          adornerLayer = AdornerLayer.GetAdornerLayer(AssociatedObject);
          adornerLayer.Add(band);
      }
  
      private void DetachBehavior()
      {
          adornerLayer.Remove(band);
      }
  }
  </code></pre>
  
  <p>RubberBandAdorner.cs:</p>
  
  <pre><code>public class RubberBandAdorner : Adorner
  {
      private Point startpoint;
      private Point currentpoint;
      private Brush brush;
      private bool flag;
      private ScrollViewer viewer;
      private ScrollBar scrollbar;
  
      public RubberBandAdorner(UIElement adornedElement)
          :base(adornedElement)
      {
          IsHitTestVisible = false;
          adornedElement.MouseMove += new MouseEventHandler(adornedElement_PreviewMouseMove);
          adornedElement.MouseLeftButtonDown += new MouseButtonEventHandler(adornedElement_PreviewMouseLeftButtonDown);
          adornedElement.PreviewMouseLeftButtonUp += new MouseButtonEventHandler(adornedElement_PreviewMouseLeftButtonUp);
          brush = new SolidColorBrush(SystemColors.HighlightColor);
          brush.Opacity = 0.3;
      }
  
      void adornedElement_PreviewMouseLeftButtonUp(object sender, MouseButtonEventArgs e)
      {
          DisposeRubberBand();
      }
  
      void adornedElement_PreviewMouseLeftButtonDown(object sender, MouseButtonEventArgs e)
      {
          ListBox _selector = AdornedElement as ListBox;
          if (_selector.SelectedItems != null &amp;&amp; (_selector.SelectionMode == SelectionMode.Extended || _selector.SelectionMode == SelectionMode.Multiple))
          {
              _selector.SelectedItems.Clear();
          }
          startpoint = Mouse.GetPosition(this.AdornedElement);
          Mouse.Capture(_selector);
          flag = true;
      }
  
      public static childItem FindVisualChild&lt;childItem&gt;(DependencyObject obj)
      where childItem : DependencyObject
      {
          // Search immediate children first (breadth-first)
          for (int i = 0; i &lt; VisualTreeHelper.GetChildrenCount(obj); i++)
          {
              DependencyObject child = VisualTreeHelper.GetChild(obj, i);
  
              if (child != null &amp;&amp; child is childItem)
                  return (childItem)child;
  
              else
              {
                  childItem childOfChild = FindVisualChild&lt;childItem&gt;(child);
  
                  if (childOfChild != null)
                      return childOfChild;
              }
          }
  
          return null;
      }
  
      void adornedElement_PreviewMouseMove(object sender, MouseEventArgs e)
      {
          if (e.LeftButton == MouseButtonState.Pressed &amp;&amp; flag)
          {
              currentpoint = Mouse.GetPosition(AdornedElement);
  
              Selector _selector = AdornedElement as Selector;
              if (viewer == null)
              {
                  viewer = FindVisualChild&lt;ScrollViewer&gt;(_selector);
              }
  
              if (scrollbar == null)
              {
                  scrollbar = FindVisualChild&lt;ScrollBar&gt;(viewer);
              }
  
              if (_selector.Items.Count &gt; 0)
              {
                  if (currentpoint.Y &gt; ((FrameworkElement)AdornedElement).ActualHeight &amp;&amp; viewer.VerticalOffset &lt; _selector.ActualHeight &amp;&amp; scrollbar.Visibility == System.Windows.Visibility.Visible)
                  {
                      startpoint.Y -= 50;
                  }
                  else if (currentpoint.Y &lt; 0 &amp;&amp; viewer.VerticalOffset &gt; 0 &amp;&amp; scrollbar.Visibility == System.Windows.Visibility.Visible)
                  {
                      startpoint.Y += 50;
                  }
              }
  
              InvalidateVisual();
  
              foreach (var obj in _selector.Items)
              {
                  ListBoxItem item = _selector.ItemContainerGenerator.ContainerFromItem(obj) as ListBoxItem;
                  if (item != null)
                  {
                      Point point = item.TransformToAncestor(AdornedElement).Transform(new Point(0, 0));
                      Rect bandrect = new Rect(startpoint, currentpoint);
                      Rect elementrect = new Rect(point.X, point.Y, item.ActualWidth, item.ActualHeight);
                      if (bandrect.IntersectsWith(elementrect))
                      {
                          item.IsSelected = true;
                      }
                      else
                      {
                          item.IsSelected = false;
                      }
                  }
              }
          }
      }
  
      protected override void OnRender(DrawingContext drawingContext)
      {
          Rect rect = new Rect(startpoint, currentpoint);
          drawingContext.DrawGeometry(brush, new Pen(SystemColors.HighlightBrush, 1), new RectangleGeometry(rect));
          base.OnRender(drawingContext);
      }
  
      private void DisposeRubberBand()
      {
          currentpoint = new Point(0, 0);
          startpoint = new Point(0, 0);
          AdornedElement.ReleaseMouseCapture();
          InvalidateVisual();
          flag = false;
      }
  }
  </code></pre>
  
  <p><em>Update:</em></p>
  
  <p>Here is the code for the <code>IsEditable</code> property of the ViewModel. Note that I am using the <code>RaisePropertyChanged</code> method from MvvmLight:</p>
  
  <pre><code>private bool isEditable;
  public bool IsEditable
  {
      get { return isEditable; }
      set {
          if(value != isEditable)
          {
              isEditable = value;
              RaisePropertyChanged("IsEditable");
          }
      }
  }
  </code></pre>