2009-04-15 155 views
0

出于某种原因,我遇到了问题在MVVM WPF应用程序中通过我的ViewModel绑定自定义用户控件。基本控件是带三个文本框的日期输入表单。我正在使用usercontrol的代码隐藏来捕获textchange事件以及一些操作。由于某些原因,添加绑定到属性从不触发。WPF MVVM +用户控件代码隐藏

XAML用户控制的:

<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> 

代码隐藏:

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; 
    } 
    } 

}

当我创建的DataTemplate中的用户控件,像这样:

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

GET和我的视图模型从未出生日期的置位。 VM上的BirthDate是一个字符串。

回答

6

检查控制和父母的DataContext

,以帮助调试您的绑定,请Bea Stollnitz's blog

基本上,这xmlns添加到您的控制

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

然后添加到您的Binding(S)

{Binding .... , diagnostics:PresentationTraceSources.TraceLevel=High } 
+0

谢谢。 UserControl的DataContext是我的问题。 – cjibo 2009-04-15 21:38:48