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.