title: WPF - Swapping ContentControl (relinking elements???)
body: <p>I'm working on a custom panel control and one of the things I'm trying to have it do is swap it's content at run-time. There's two states to this control: Maximized and Normal. When the user clicks a button on the control the state switches. There's two properties on this control: MaximizedContent and MinimizedContent. When the button to swap states is clicked, the Content property of the control needs to swap between MaximizedContent and MinimizedContent. The problem comes when there's bindings inside of the MaximizedContent or MinimizedContent. The don't seem to be part of the "Tree" and therefore binding doesn't work... at least that's my theory. So my question is how do I make them part of the tree?</p>
  
  <p>Here's a simplified example:</p>
  
  <p><strong>MainWindow.xaml</strong></p>
  
  <pre><code>&lt;Window x:Class="SwappingContentTest.MainWindow"
          Loaded="Window_Loaded"
          xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
          xmlns:local="clr-namespace:SwappingContentTest"
          xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"&gt;
  
      &lt;StackPanel  HorizontalAlignment="Left"&gt;
          &lt;Button x:Name="swapContentButton"
                  Click="swapContentButton_Click"
                  Content="Swap Content" /&gt;
  
          &lt;local:SwappableContentControl x:Name="swappableControl"&gt;
              &lt;local:SwappableContentControl.MaximizedContent&gt;
                  &lt;StackPanel&gt;
                      &lt;CheckBox x:Name="maximizedCheckBox"
                                Content="Maximized CheckBox" /&gt;
                      &lt;Button x:Name="maximizedButton"
                              Content="Maximized Button"
                              IsEnabled="{Binding ElementName=maximizedCheckBox, Path=IsChecked}" /&gt;
                  &lt;/StackPanel&gt;
              &lt;/local:SwappableContentControl.MaximizedContent&gt;
  
              &lt;local:SwappableContentControl.MinimizedContent&gt;
                  &lt;StackPanel&gt;
                      &lt;CheckBox x:Name="minimizedCheckBox"
                                Content="Minimized CheckBox" /&gt;
                      &lt;Button x:Name="minimizedButton"
                              Content="Minimized Button"
                              IsEnabled="{Binding ElementName=minimizedCheckBox, Path=IsChecked}" /&gt;
                  &lt;/StackPanel&gt;
              &lt;/local:SwappableContentControl.MinimizedContent&gt;
          &lt;/local:SwappableContentControl&gt;
  
          &lt;CheckBox x:Name="standardCheckBox"
                    Content="Standard CheckBox"
                    Margin="0,20,0,0"/&gt;
          &lt;Button x:Name="standardButton"
                  Content="StandardButton"
                  IsEnabled="{Binding ElementName=standardCheckBox, Path=IsChecked}" /&gt;
      &lt;/StackPanel&gt;
  &lt;/Window&gt;
  </code></pre>
  
  <p><strong>MainWindow.cs</strong></p>
  
  <pre><code>namespace SwappingContentTest
  {
      public partial class MainWindow : Window
      {
          public MainWindow()
          {
              InitializeComponent();
          }
  
          private void Window_Loaded(object sender, RoutedEventArgs e)
          {
              swappableControl.SwapContent();
          }
  
          private void swapContentButton_Click(object sender, RoutedEventArgs e)
          {
              swappableControl.SwapContent();
          }
      }
  }
  </code></pre>
  
  <p><strong>SwappableContentControl.cs</strong></p>
  
  <pre><code>namespace SwappingContentTest
  {
      public class SwappableContentControl : ContentControl
      {
          public static readonly DependencyProperty MaximizedContentProperty = DependencyProperty.Register("MaximizedContent", typeof(object), typeof(SwappableContentControl));
  
          public static readonly DependencyProperty MinimizedContentProperty = DependencyProperty.Register("MinimizedContent", typeof(object), typeof(SwappableContentControl));
  
          public static readonly DependencyProperty StateProperty = DependencyProperty.Register("State", typeof(SwappableContentControlState), typeof(SwappableContentControl),
              new PropertyMetadata(new PropertyChangedCallback(StatePropertyCallback)));
  
          public static void StatePropertyCallback(DependencyObject d, DependencyPropertyChangedEventArgs e)
          {
              SwappableContentControl control = (SwappableContentControl)d;
              if ((SwappableContentControlState)e.NewValue == SwappableContentControlState.Maximized)
              {
                  control.Content = control.MaximizedContent;
              }
              else
              {
                  control.Content = control.MinimizedContent;
              }
          }
  
          public object MaximizedContent
          {
              get { return GetValue(MaximizedContentProperty); }
              set { SetValue(MaximizedContentProperty, value); }
          }
  
  
          public object MinimizedContent
          {
              get { return GetValue(MinimizedContentProperty); }
              set { SetValue(MinimizedContentProperty, value); }
          }
  
  
          public SwappableContentControlState State
          {
              get { return (SwappableContentControlState)GetValue(StateProperty); }
              set { SetValue(StateProperty, value); }
          }
  
          public void SwapContent()
          {
              if (State == SwappableContentControlState.Maximized)
              {
                  State = SwappableContentControlState.Normal;
              }
              else
              {
                  State = SwappableContentControlState.Maximized;
              }
          }
      }
  }
  </code></pre>
  
  <p>Here's a link to the project:
  <a href="http://www.freewebs.com/thrash505/SwappingContentTest.zip" rel="nofollow noreferrer">http://www.freewebs.com/thrash505/SwappingContentTest.zip</a></p>