2011-07-26 10 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 내가 내 에서 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> 
을이 컨트롤을 사용하려면

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

뭔가

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

처럼 내 UserControl을 결합하는 데 사용할 DateControl의 속성을 정의합니다. 난 당신이 DateControlViewModelDateControlDataContex톤를 설정해야 saperate MVVM

+0

[편집 도움말] (http://stackoverflow.com/editing-help)을 읽어야합니다. 서식이 매우 손상되었습니다. –

+0

이 답변을 확인하십시오. http://stackoverflow.com/questions/76412/expose-dependencyproperty – Aardvark

+0

UserControl에 Date 속성을 추가 한 이유는 무엇입니까? 뷰는 코드 없이도 존재할 수 있으며 뷰 모델 만 사용하여 모든 작업을 수행 할 수 있습니다. – vorrtex

답변

1

먼저 사용에서 MainPage.xaml에있는 그것의 속성을 바인딩 할 수 있도록 내 UserControl을 변경 어떻게

. 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에서 바인딩을 활성화합니다.

관련 문제