2011-07-26 29 views
3

我遇到问题在MVVM银色灯光应用程序中通过我的ViewModel绑定自定义用户控件。基本控件是带三个文本框的日期输入表单。我正在使用MVVM在三个属性中获取文本框数据,然后将其验证为Date。 绑定下面的控制到MVVM对我来说工作得很好。在silvelight用户控件中自定义绑定

XAML用户控制:DateControl.xaml

<UserControl x:Class="DatePicker.DateControl" 
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
    xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 
    xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
    mc:Ignorable="d"> 

    <Grid x:Name="LayoutRoot" Background="White" 
      HorizontalAlignment="Center"> 
     <StackPanel Orientation="Horizontal"> 
      <StackPanel Orientation="Horizontal"> 
       <TextBox MaxLength="2" TabIndex="0" Style="{StaticResource BirthDDTextBoxStyle}" 
           Text="{Binding BirthDay,Mode=TwoWay,ValidatesOnNotifyDataErrors=True, NotifyOnValidationError=True}"/> 
       <TextBlock Style="{StaticResource TextBlockStyle_DateSeperator}"/> 
       <TextBox MaxLength="2" TabIndex="1" Style="{StaticResource BirthDDTextBoxStyle}" Text="{Binding BirthMonth, Mode=TwoWay,ValidatesOnNotifyDataErrors=True, NotifyOnValidationError=True}"/> 
       <TextBlock Style="{StaticResource TextBlockStyle_DateSeperator}"/> 
       <TextBox MaxLength="4" TabIndex="2" Style="{StaticResource BirthYYTextBoxStyle}" Text="{Binding BirthYear, Mode=TwoWay, ValidatesOnNotifyDataErrors=True, NotifyOnValidationError=True}"/> 
       <Button Content="Show" Width="100" Height="30" Click="Button_Click"/> 
      </StackPanel> 
     </StackPanel> 
    </Grid> 
</UserControl> 

DateControlViewModel是

namespace DatePicker 
{ 
    public class DatePickerViewModel : EntityViewModel 
    { 
     public DatePickerViewModel() 
     { 

     } 

     private DateTime birthDate; 
     public DateTime BirthDate 
     { 
      get 
      { 

       return birthDate; 
      } 
      set 
      { 
       birthDate = value; 
      } 
     } 
     private string birthDay; 
     public string BirthDay 
     { 
      get { return birthDay; } 
      set 
      { 
       birthDay = value; 
       PropertyChangedHandler("BirthDay"); 
       ValidateBirthDay("BirthDay", value); 
      } 
     } 

     private string birthMonth; 
     public string BirthMonth 
     { 
      get { return birthMonth; } 
      set 
      { 
       birthMonth = value; 
       PropertyChangedHandler("BirthMonth"); 
       ValidateBirthMonth("BirthMonth", value); 
      } 
     } 

     private string birthYear; 
     public string BirthYear 
     { 
      get { return birthYear; } 
      set 
      { 
       birthYear = value; 
       PropertyChangedHandler("BirthYear"); 
       ValidateBirthYear("BirthYear", value); 
      } 
     } 

     private void ValidateDOB() 
     { 
      ClearErrorFromProperty("BirthDay"); 
      ClearErrorFromProperty("BirthMonth"); 
      ClearErrorFromProperty("BirthYear"); 
      if (string.IsNullOrEmpty(BirthDay)) 
       ValidateBirthDay("BirthDay", BirthDay); 
      if (string.IsNullOrEmpty(BirthMonth)) 
       ValidateBirthMonth("BirthMonth", BirthMonth); 
      if (string.IsNullOrEmpty(BirthYear)) 
       ValidateBirthYear("BirthYear", BirthYear); 
      if (!string.IsNullOrEmpty(BirthDay) && !string.IsNullOrEmpty(BirthMonth) && !string.IsNullOrEmpty(BirthYear)) 
       SetDateOfBirth(); 
     } 

     private void ValidateBirthDay(string propertyName, string value) 
     { 
      ClearErrorFromProperty(propertyName); 
      if (String.IsNullOrEmpty(value)) 
       AddErrorForProperty(propertyName, "Resources.PatientImport.EmptyDayMessage"); 
      else 
       if (Common.IsNumber(value)) 
       { 
        int day = Convert.ToInt32(value); 
        if (day > 31 || day < 1) 
         AddErrorForProperty(propertyName, "Resources.PatientImport.InvalidDayMessage"); 
       } 
       else 
        AddErrorForProperty(propertyName, "Resources.PatientImport.InvalidDayMessage"); 
     } 

     private void ValidateBirthMonth(string propertyName, string value) 
     { 
      ClearErrorFromProperty(propertyName); 
      if (String.IsNullOrEmpty(value)) 
       AddErrorForProperty(propertyName, "Resources.PatientImport.EmptyMonthMessage"); 
      else 
       if (Common.IsNumber(value)) 
       { 
        int month = Convert.ToInt32(value); 
        if (month > 12 || month < 1) 
         AddErrorForProperty(propertyName, "Resources.PatientImport.InvalidMonthMessage"); 
       } 
       else 
        AddErrorForProperty(propertyName, "Resources.PatientImport.InvalidMonthMessage"); 
     } 

     private void ValidateBirthYear(string propertyName, string value) 
     { 
      ClearErrorFromProperty(propertyName); 
      if (String.IsNullOrEmpty(value)) 
       AddErrorForProperty(propertyName, "Resources.PatientImport.EmptyYearMessage"); 
      else 
       if (Common.IsNumber(value)) 
       { 
        int year = Convert.ToInt32(value); 
        if (year.ToString().Length > 4 || year.ToString().Length < 4) 
         AddErrorForProperty(propertyName, "Resources.PatientImport.InvalidYearMessage"); 
       } 
       else 
        AddErrorForProperty(propertyName, "Resources.PatientImport.InvalidYearMessage"); 
     } 

     private void SetDateOfBirth() 
     { 
      string dateString = BirthDay + "-" + BirthMonth + "-" + BirthYear; 
      DateTime date; 
      if (!DateTime.TryParse(dateString.ToString(), out date)) 
      { 
       ClearErrorFromProperty("BirthDay"); 
       ClearErrorFromProperty("BirthMonth"); 
       ClearErrorFromProperty("BirthYear"); 
       AddErrorForProperty("BirthDay", "Resources.PatientImport.InvalidDayMessage"); 
       AddErrorForProperty("BirthMonth", "Resources.PatientImport.InvalidMonthMessage"); 
       AddErrorForProperty("BirthYear", "Resources.PatientImport.InvalidYearMessage"); 
      } 
      else 
       BirthDate = date; 
     } 
    } 
} 

我想在我的MainPage.xaml中

<UserControl x:Class="DatePicker.MainPage" 
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
    xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 
    xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
    xmlns:local="clr-namespace:DatePicker" 
    mc:Ignorable="d" 
    d:DesignHeight="300" d:DesignWidth="400"> 

    <Grid x:Name="LayoutRoot" Background="White"> 
     <local:DateControl /> 
    </Grid> 
</UserControl> 
使用这个控制

我要定义一个DateControl财产,我会用我的用户控件绑定MainPage.xaml中的视图模型

喜欢的东西

<Grid x:Name="LayoutRoot" Background="White"> 
    <local:DateControl Date="{Binding BirthDate, Mode=TwoWay, ValidatesOnNotifyDataErrors=True, NotifyOnValidationError=True}"/> 
</Grid> 

出生日期是字符串类型属性。

如何更改我的用户,这样我可以在MainPage.xaml中使用saperate MVVM

+0

你应该阅读[编辑帮助](http://stackoverflow.com/editing-help),格式很破碎... –

+0

检查这个答案。 http://stackoverflow.com/questions/76412/expose-dependencyproperty – Aardvark

+0

为什么你将Date属性添加到你的UserControl?视图可以在没有代码的情况下存在,一切都可以仅使用视图模型来完成。 – vorrtex

回答

1

首先,你需要的DataContex吨您DateControl的设置为DateControlViewModel其属性绑定。在您的DateControl xaml中,您可以使用此想法,或将其设置在代码的某处(如DateControl的构造函数),或者将数据绑定到要使用的视图模型DataContext

<UserControl.Resources> 
     <viewModels:ViewDisplayTemplatesViewModel x:Key="viewModel" /> 
    </UserControl.Resources> 

    <UserControl.DataContext> 
     <Binding Source="{StaticResource viewModel}"/> 
    </UserControl.DataContext> 

其次,你需要在你的DateControl定义依赖属性,如土豚在注释中。我使用了propdp代码片段(我认为这是与Silverlight安装一起提供的,如果没有,您可以在此MSDN article中看到它)。依赖属性启用xaml中的绑定。