WPF MVVM + UserControl с кодом позади - PullRequest
0 голосов
/ 15 апреля 2009

По какой-то причине у меня возникают проблемы с привязкой пользовательского элемента управления через мою ViewModel в приложении MVFM WPF. Основным элементом управления является форма ввода даты с тремя текстовыми полями. Я использую codebehind для usercontrol, чтобы захватить событие textchange и поэтому некоторые манипуляции. По какой-то причине Добавление привязки к свойству никогда не срабатывает.

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>

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

}

Когда я создаю usercontrol в DataTemplate, вот так:

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

Получение и набор BirthDate в моей ViewModel никогда не устанавливаются. Дата рождения на ВМ является строкой.

1 Ответ

6 голосов
/ 15 апреля 2009

Проверьте DataContext элемента управления и родительского элемента.

, чтобы помочь с отладкой ваших привязок, загляните в блог Bea Stollnitz

в основном, добавьте это xmlns к вашему контролю

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

затем добавьте это к своим Binding (s)

{Binding ....    , diagnostics:PresentationTraceSources.TraceLevel=High }
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...