title: WPF TextBox Extension unable to use MahApps TextBoxHelper
body: <p>I have an extended wpf textbox and I would like to use MahApps TextBoxHelper to add a watermark. Using regular textboxes worked just fine but as soon as I tried to replace them with my extended textbox <code>TouchTextBox</code> the watermarks disappeared along with the Metro style. My extended textbox is designed to work with a custom touch keyboard and it has a number of events geared toward handling this feature:</p>
  
  <p>XAML:</p>
  
  <pre><code>&lt;TextBox x:Class="MyNamespaceHERE.TouchTextBox"
       xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
       xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
       xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
       xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 
       xmlns:Controls="clr-namespace:MahApps.Metro.Controls;assembly=MahApps.Metro"
       xmlns:local="clr-namespace:MyNamespaceHERE"
       mc:Ignorable="d" 
       GotFocus="TouchTextBox_GotFocus"
       LostFocus="TouchTextBox_LostFocus"&gt;
  &lt;/TextBox&gt;
  </code></pre>
  
  <p>Code Behind:</p>
  
  <pre><code>public partial class TouchTextBox : TextBox
  {
  
      public TouchTextBox()
      {
          InitializeComponent();
  
      }
  
      private void TouchTextBox_GotFocus(object sender, RoutedEventArgs e)
      {
          StaticEvents.OnShowTouchKeyboard(sender, e);
          StaticEvents.TouchKeyboardKeyTouch += StaticEvents_TouchKeyboardKeyTouch;
          StaticEvents.TouchKeyboardSpaceTouch += StaticEvents_TouchKeyboardSpaceTouch;
          StaticEvents.TouchKeyboardBackspaceTouch += StaticEvents_TouchKeyboardBackspaceTouch;
      }
  
      private void StaticEvents_TouchKeyboardBackspaceTouch(object sender, EventArgs e)
      {
          int i = CaretIndex;
          if (CaretIndex == 0) return;
          Text = Text.Remove(CaretIndex - 1, 1);
          CaretIndex = i - 1;
      }
  
      private void StaticEvents_TouchKeyboardSpaceTouch(object sender, EventArgs e)
      {
          int i = CaretIndex;
          Text = Text.Insert(CaretIndex, " ");
          CaretIndex = i + 1;
      }
  
      private void StaticEvents_TouchKeyboardKeyTouch(object sender, EventArgs e)
      {
          int i = CaretIndex;
          string t = (sender as Button).Content.ToString();
          Text = Text.Insert(CaretIndex, t);
          CaretIndex = i + 1;
      }
  
      private void TouchTextBox_LostFocus(object sender, RoutedEventArgs e)
      {
          StaticEvents.OnHideTouchKeyboard(sender, e);
          StaticEvents.TouchKeyboardKeyTouch -= StaticEvents_TouchKeyboardKeyTouch;
          StaticEvents.TouchKeyboardSpaceTouch -= StaticEvents_TouchKeyboardSpaceTouch;
          StaticEvents.TouchKeyboardBackspaceTouch -= StaticEvents_TouchKeyboardBackspaceTouch;
      }
  }
  </code></pre>
  
  <p>I followed the advice I found in this solution <a href="https://stackoverflow.com/questions/32230427/extending-textbox-in-wpf-using-mahapps-keeping-style">here</a> but so far it has not solved the issue. According to the solution, I need to add a style that is based on TextBox, so here is what I have in my Resource Dictionary:</p>
  
  <pre><code>&lt;Style TargetType="local:TouchTextBox" BasedOn="{StaticResource {x:Type TextBox}}" x:Key="TouchTextBoxStyle"/&gt;
  </code></pre>
  
  <p>I added this style to each instance of my TouchTextBox controls so that they look like this:</p>
  
  <pre><code>&lt;local:TouchTextBox x:Name="UsernameTextBox" Controls:TextBoxHelper.Watermark="Username" Width="200" Text="{Binding Username}" Style="{StaticResource TouchTextBoxStyle}"/&gt;
  &lt;local:TouchTextBox x:Name="PasswordTextBox" Controls:TextBoxHelper.Watermark="Password" Width="200" Margin="0,30,0,0" Text="{Binding Password}" Style="{StaticResource TouchTextBoxStyle}"/&gt;
  </code></pre>
  
  <p>So far no luck. How can I get back all the great features of MahApps' TextBoxHelper with my custom TouchTextBox user control? I really appreciate any guidance you can provide.</p>
  
  <p>Edit:</p>
  
  <p>I took Joel Lucsy's advice and implemented a <code>TouchTextBoxHelper</code> class to handle the <code>DependencyProperty</code> for my event handling:</p>
  
  <pre><code>public class TouchTextBoxHelper : DependencyObject
  {
      public static readonly DependencyProperty IsTouchKeyboardTargetProperty = DependencyProperty.Register("IsTouchKeyboardTarget", typeof(bool), typeof(TouchTextBoxHelper), new FrameworkPropertyMetadata(false, IsTouchKeyboardTargetChanged));
  
  
      [AttachedPropertyBrowsableForType(typeof(TextBox))]
      public static bool GetIsTouchKeyboardTargetEnabled(DependencyObject obj)
      {
          return (bool)obj.GetValue(IsTouchKeyboardTargetProperty);
      }
  
      [AttachedPropertyBrowsableForType(typeof(TextBox))]
      public static void SetIsTouchKeyboardTargetEnabled(DependencyObject obj, bool value)
      {
          obj.SetValue(IsTouchKeyboardTargetProperty, value);
          TextBox tb = obj as TextBox;
          if (tb == null) return;
          if (value)
          {
  
              tb.GotFocus += TextBoxBaseGotFocus;
              tb.LostFocus += TextBoxBaseLostFocus;
          }
          else
          {
              tb.GotFocus -= TextBoxBaseGotFocus;
              tb.LostFocus -= TextBoxBaseLostFocus;
          }
      }
  
      private static void IsTouchKeyboardTargetChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
      {
          var tb = d as TextBox;
          if (null == tb)
          {
              throw new InvalidOperationException("The property 'IsTouchKeyboardTarget' may only be set on TextBox elements.");
          }
  
          if (e.OldValue != e.NewValue)
          {
              //tb.SetValue(SpellCheck.IsEnabledProperty, (bool)e.NewValue);
              if ((bool)e.NewValue)
              {
                  tb.GotFocus += TextBoxBaseGotFocus;
                  tb.LostFocus += TextBoxBaseLostFocus;
              }
              else
              {
                  tb.GotFocus -= TextBoxBaseGotFocus;
                  tb.LostFocus -= TextBoxBaseLostFocus;
              }
          }
      }
  
      private static void TextBoxBaseGotFocus(object sender, RoutedEventArgs e)
      {
          TouchTextBoxEvents.tb = sender as TextBox;
          StaticEvents.OnShowTouchKeyboard(sender, e);
          StaticEvents.TouchKeyboardKeyTouch += TouchTextBoxEvents.StaticEvents_TouchKeyboardKeyTouch;
          StaticEvents.TouchKeyboardSpaceTouch += TouchTextBoxEvents.StaticEvents_TouchKeyboardSpaceTouch;
          StaticEvents.TouchKeyboardBackspaceTouch += TouchTextBoxEvents.StaticEvents_TouchKeyboardBackspaceTouch;
      }
  
      private static void TextBoxBaseLostFocus(object sender, RoutedEventArgs e)
      {
          StaticEvents.OnHideTouchKeyboard(sender, e);
          StaticEvents.TouchKeyboardKeyTouch -= TouchTextBoxEvents.StaticEvents_TouchKeyboardKeyTouch;
          StaticEvents.TouchKeyboardSpaceTouch -= TouchTextBoxEvents.StaticEvents_TouchKeyboardSpaceTouch;
          StaticEvents.TouchKeyboardBackspaceTouch -= TouchTextBoxEvents.StaticEvents_TouchKeyboardBackspaceTouch;
      }
  }
  
  public class TouchTextBoxEvents
  {
      public static TextBox tb = null;
      public static void StaticEvents_TouchKeyboardKeyTouch(object sender, EventArgs e)
      {
          int i = tb.CaretIndex;
          string t = (sender as Button).Content.ToString();
          tb.Text = tb.Text.Insert(tb.CaretIndex, t);
          tb.CaretIndex = i + 1;
      }
  
      public static void StaticEvents_TouchKeyboardBackspaceTouch(object sender, EventArgs e)
      {
          int i = tb.CaretIndex;
          if (tb.CaretIndex == 0) return;
          tb.Text = tb.Text.Remove(tb.CaretIndex - 1, 1);
          tb.CaretIndex = i - 1;
      }
  
      public static void StaticEvents_TouchKeyboardSpaceTouch(object sender, EventArgs e)
      {
          int i = tb.CaretIndex;
          tb.Text = tb.Text.Insert(tb.CaretIndex, " ");
          tb.CaretIndex = i + 1;
      }
  }
  </code></pre>
  
  <p>It's kind of horifying but it works!</p>