0

For some reason I'm having issues Binding a custom User Control up through my ViewModel in an MVVM WPF application. The basic control is a Date entry form with three text boxes. I am using the codebehind for the usercontrol to capture the textchange event and so some manipulation. For some reason Adding Binding to the property never triggers.

XAML of user Control:

<UserControl x:Class="MYLibray.DateBox"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Height="300" Width="800">
<StackPanel>

    <Border CornerRadius="10" Height="200" BorderBrush="Gray" Background="Gray">
    <StackPanel Orientation="Horizontal" OpacityMask="{x:Null}" HorizontalAlignment="Center">
    <TextBox Name="txtMonth" Height="100" Width="90" BorderThickness="0,0,0,5" Background="{x:Null}" Text="" FontSize="72" TextChanged="TextChanged">
        <TextBox.BorderBrush>
            <LinearGradientBrush EndPoint="0.5,1" StartPoint="0.5,0">
                <GradientStop Color="#FF000000" Offset="0"/>
                <GradientStop Color="#FF000000" Offset="1"/>
            </LinearGradientBrush>
        </TextBox.BorderBrush>
    </TextBox>
            <TextBlock Text="/" FontSize="72" Height="100" Width="50" />
            <TextBox x:Name="txtDay" Height="100" Width="90" Background="{x:Null}" BorderThickness="0,0,0,5" VerticalAlignment="Stretch" FontSize="72" TextChanged="TextChanged">
                <TextBox.BorderBrush>
                    <LinearGradientBrush EndPoint="0.5,1" StartPoint="0.5,0">
                        <GradientStop Color="#FF000000" Offset="0"/>
                        <GradientStop Color="#FF000000" Offset="1"/>
                    </LinearGradientBrush>
                </TextBox.BorderBrush>
            </TextBox>
            <TextBlock Text="/19" FontSize="72" Height="100" Width="Auto" />
            <TextBox x:Name="txtYear" Height="100" Width="90" Background="{x:Null}" BorderThickness="0,0,0,5"  FontSize="72" TextChanged="TextChanged">
                <TextBox.BorderBrush>
                    <LinearGradientBrush EndPoint="0.5,1" StartPoint="0.5,0">
                        <GradientStop Color="#FF000000" Offset="0"/>
                        <GradientStop Color="#FF000000" Offset="1"/>
                    </LinearGradientBrush>
                </TextBox.BorderBrush>
            </TextBox>
    </StackPanel>
    </Border>

</StackPanel>

CodeBehind:

public partial class DateBox : UserControl

{

  private string _date = "";
  public static DependencyProperty TextProperty = DependencyProperty.RegisterAttached("DateText", typeof(string), typeof(DateBox), new PropertyMetadata(TextPropertyChanged));
  public static DependencyProperty EnabledProperty = DependencyProperty.RegisterAttached("Enabled", typeof(bool), typeof(DateBox), null);

  public DateBox()
  {                                 
     InitializeComponent();
     this.DataContext = this;
     txtMonth.Focus();
  }

  public bool Enabled
  {
     get
     {
        return (bool)GetValue(DateBox.EnabledProperty);
     }
     set
     {
        SetValue(DateBox.EnabledProperty, value);

        txtDay.IsEnabled = value;
        txtMonth.IsEnabled = value;
        txtYear.IsEnabled = value;
     }
  }

  public string DateText
  {
     get
     {
        return (string)this.GetValue(TextProperty);
     }
     set
     {
        this.SetValue(TextProperty, value);
     }
  }

  static void TextPropertyChanged(DependencyObject property,DependencyPropertyChangedEventArgs args)
  {
     ((DateBox)property).OnTextPropertyChanged((object)args.NewValue);
  }

  private void OnTextPropertyChanged(object newValue)
  {
     _date = newValue.ToString();
     this.UpdateLayout();
     DateTime d;
     if (DateTime.TryParse(_date, out d))
     {
        txtDay.Text = d.Day.ToString();
        txtMonth.Text = d.Month.ToString();
        txtYear.Text = (d.Year - 1900).ToString();
     }
     else
     {
        txtDay.Text = "";
        txtMonth.Text = "";
        txtYear.Text = "";
     }

     DateText = d.ToShortDateString();
  }

  bool AreAllValidNumericChars(string str)
  {
     bool ret = true;
     if (str == System.Globalization.NumberFormatInfo.CurrentInfo.PositiveSign)
     {
        return ret;
     }
     int l = str.Length;
     for (int i = 0; i < l; i++)
     {
        char ch = str[i];
        ret &= Char.IsDigit(ch);
     }

     return ret;
  }

  private void TextChanged(object sender, TextChangedEventArgs e)
  {

     TextBox txt = (TextBox)sender;

     switch (txt.Name)
     {
        case "txtMonth":
           if (txt.Text.Length == 1)
           {
              if (Convert.ToInt32(txt.Text) > 1)
              {
                 string value = txt.Text;
                 txt.Text = "0" + value;
                 txtDay.Focus();
              }
           }
           if (txt.Text.Length == 2)
           {
              txtDay.Focus();
           }
           break;
        case "txtDay":
           if (txt.Text.Length == 1)
           {
              if (Convert.ToInt32(txt.Text) > 3)
              {
                 string value = txt.Text;
                 txt.Text = "0" + value;
                 txtYear.Focus();
              }
           }
           if (txt.Text.Length == 2)
           {
              txtYear.Focus();
           }
           break;

        case "txtYear":
           if (txt.Text.Length == 2)
           {
              DateTime d;
              string datestring = txtMonth.Text + "/" + txtDay.Text + "/19" + txtYear.Text;
              if (DateTime.TryParse(datestring,out d))
              {
                 DateText = d.ToShortDateString();
              }
           }
           break;
        default:
           break;
     }
  }

}

When I create the usercontrol in the DataTemplate like so:

<uc:DateBox DateText="{Binding BirthDate}" />

The get and set of BirthDate in my ViewModel never get set. BirthDate on the VM is a String.

1 Answer 1

6

Check the DataContext of the control and of the parent.

to help with debugging your bindings, check out Bea Stollnitz's blog

basically, add this xmlns to your control

xmlns:diagnostics="clr-namespace:System.Diagnostics;assembly=WindowsBase"

then add this to your Binding(s)

{Binding ....    , diagnostics:PresentationTraceSources.TraceLevel=High }
Sign up to request clarification or add additional context in comments.

1 Comment

Thank you. The DataContext of the UserControl was my issue.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.