2009-04-15 12 views
0

Aus irgendeinem Grund habe ich Probleme beim Binden eines benutzerdefinierten Benutzersteuerelements über mein ViewModel in einer MVVM WPF-Anwendung. Das grundlegende Steuerelement ist ein Datumseingabeformular mit drei Textfeldern. Ich benutze das Codebehind für die Benutzersteuerung, um das Textänderungsereignis und so einige Manipulation zu erfassen. Aus irgendeinem Grund wird das Hinzufügen der Bindung zur Eigenschaft nie ausgelöst.WPF MVVM + UserControl mit Code hinter

XAML der Benutzerkontrolle:

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

}

Wenn ich schaffen das Usercontrol in der Datatemplate wie so:

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

Die get und eine Reihe von Birth in meinem Viewmodel nie fertig. BirthDate auf der VM ist ein String.

Antwort

6

Überprüfen Sie die DataContext der Steuerung und des übergeordneten.

mit Debuggen Bindungen zu helfen, Besuche Bea Stollnitz's blog

im Grunde, diese

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

dann fügen Sie diese zu Ihrer Binding (s)

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

Sie xmlns Ihrem Steuerelement hinzufügen danken . Der DataContext des UserControls war mein Problem. – cjibo