2009-04-15 7 views
0

Pour une raison quelconque, je rencontre des problèmes Liaison d'un contrôle utilisateur personnalisé à travers mon ViewModel dans une application MVVM WPF. Le contrôle de base est un formulaire d'entrée de date avec trois zones de texte. J'utilise le codebehind pour la commande usercontrol pour capturer l'événement textchange et donc une manipulation. Pour une raison quelconque, l'ajout de liaison à la propriété ne se déclenche jamais.WPF MVVM + UserControl avec le code derrière

XAML de contrôle utilisateur:

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

}

Lorsque je crée le usercontrol dans le DataTemplate comme ceci:

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

Le get et set de BirthDate dans mon ViewModel ne sont jamais mis. BirthDate sur la machine virtuelle est une chaîne.

Répondre

6

Vérifiez le DataContext du contrôle et du parent.

pour aider à déboguer vos fixations, consultez Bea Stollnitz's blog

essentiellement, ajoutez cette xmlns à votre commande

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

puis ajoutez ceci à votre Binding (s)

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

Merci . Le DataContext de UserControl était mon problème. – cjibo