2011-01-27 5 views
1

누구나 INotifyDataErrorInfo 인터페이스를 성공적으로 적용하고 AutoCompleteBox에 바인딩했습니다. 나는 이것을 시도했지만 응답이 없습니다. 컨트롤이 다른 컨트롤 (빨간색 테두리 및 경고 툴팁)으로 응답하지 않습니다. 또한 유효성 검사 요약 컨트롤에 오류가 표시되지 않습니다.Silverlight의 AutoCompleteBox 및 INotifyDataErrorInfo

나는 표준 TextBoxes 및 DatePickers를 성공적으로 설정했으며 이들은 인터넷상의 사람들이 친절하게 제공하는 많은 예제에 따라 완벽하게 작동합니다.

내 화면의 일관성에 대한 대답이 있다면 좋을 것입니다. 왜냐하면 저장하기 위해 버튼을 사용할 수 있도록 INotifyDataErrorInfo와 함께 제공되는 HasErrors 속성에 간단히 바인딩하고 싶습니다. 이 상자가 올바른지 확인하려면 추가 코드없이이 작업을 수행하십시오.

현재 MVVMLight EventToCommand 바인딩을 사용하고 LostFocus 이벤트를 등록하여이를 다르게 처리합니다.

- :
<sdk:AutoCompleteBox x:Name="TransferTypeTextBox" SelectedItem="{Binding Path=SelectedTransferType, Mode=TwoWay, ValidatesOnNotifyDataErrors=True, NotifyOnValidationError=True}" ItemsSource="{Binding Path=TransferTypes}" IsTextCompletionEnabled="True" Grid.Row="1" Grid.Column="1" Margin="0,3" Width="238" HorizontalAlignment="Left" FontFamily="/PtrInput_Silverlight;component/Fonts/Fonts.zip#Calibri" FontSize="13.333"> 
     <i:Interaction.Triggers> 
      <i:EventTrigger EventName="LostFocus"> 
       <cmd:EventToCommand Command="{Binding TransferTypeLostFocusCommand}" PassEventArgsToCommand="True"/> 
      </i:EventTrigger> 
     </i:Interaction.Triggers> 
</sdk:AutoCompleteBox> 

는 뷰 모델에서 나는 다음 상자의 목록에서 항목을 비어 있지 않는 한 상자를 떠나거나 일치에서 사용자를 방지, 텍스트 상자에 RoutedEventArgs.OriginalSource 캐스트 등과 같은 텍스트를 얻을
private void OnTransferTypeLostFocus(RoutedEventArgs e) 
    { 
     System.Windows.Controls.TextBox box = (System.Windows.Controls.TextBox)e.OriginalSource; 

     // If user inputs text but doesn't select one item, show message. 
     if (this.Ptr.TransferType == null && !string.IsNullOrEmpty(box.Text)) 
     { 
      MessageBox.Show("That is not a valid entry for Transfer Type", "Transfer type", MessageBoxButton.OK); 
      box.Focus(); 
     } 
    } 

답변

1

가능한 간단한 예제로 작성하려고했습니다. 내 모델은 SearchText 속성의 변경 사항을 확인하고 유효성 검사 속성을 업데이트합니다.

public class MainViewModel : INotifyPropertyChanged, INotifyDataErrorInfo 
{ 
    private Dictionary<string, List<string>> ErrorMessages = new Dictionary<string, List<string>>(); 

    public MainViewModel() 
    { 
     //Validation works automatically for all properties that notify about the changes 
     this.PropertyChanged += new PropertyChangedEventHandler(ValidateChangedProperty); 
    } 

    //Validate and call 'OnErrorChanged' for reflecting the changes in UI 
    private void ValidateChangedProperty(object sender, PropertyChangedEventArgs e) 
    { 
     if (e.PropertyName == "HasErrors") //avoid recursion 
      return; 

     this.ValidateProperty(e.PropertyName); 
     OnErrorsChanged(e.PropertyName); 
     OnPropertyChanged("HasErrors"); 
    } 

    //Just compare a received value with a correct value, it's a simple rule for demonstration 
    public void ValidateProperty(string propertyName) 
    { 
     if (propertyName == "SearchText") 
     { 
      this.ErrorMessages.Remove(propertyName); 
      if (SearchText != "Correct value") 
       this.ErrorMessages.Add("SearchText", new List<string> { "Enter a correct value" }); 
     } 

    } 

    private string searchText; 

    public string SearchText 
    { 
     get { return searchText; } 
     set 
     { 
      searchText = value; 
      OnPropertyChanged("SearchText"); 
     } 
    } 



    #region INotifyDataErrorInfo 

    public IEnumerable GetErrors(string propertyName) 
    { 
     return this.ErrorMessages.Where(er => er.Key == propertyName).SelectMany(er => er.Value); 
    } 

    public bool HasErrors 
    { 
     get { return this.ErrorMessages.Count > 0; } 
    } 

    public event EventHandler<DataErrorsChangedEventArgs> ErrorsChanged = delegate { }; 

    private void OnErrorsChanged(string propertyName) 
    { 
     ErrorsChanged(this, new DataErrorsChangedEventArgs(propertyName)); 
    } 
    #endregion 


    public event PropertyChangedEventHandler PropertyChanged = delegate { }; 

    protected virtual void OnPropertyChanged(string propertyName) 
    { 
     this.PropertyChanged(this, new PropertyChangedEventArgs(propertyName)); 
    } 
} 

그리고 XAML :

<sdk:AutoCompleteBox Text="{Binding SearchText, Mode=TwoWay}" /> 
<Button IsEnabled="{Binding HasErrors, Converter={StaticResource NotConverter}}" Content="Save"/> 

제어는 빨간색 테두리를 가지고 있으며, 모델에 오류가있을 때 버튼을 사용할 수 없습니다.

+0

감사합니다. 나는 이것을 시도 할 것입니다. 마음에 들지 않으면 ViewModel에서 AutoCompleteBox를 지울 수 있는지 묻고 싶습니다. SelectedItem 및 텍스트 바인딩 있지만 ViewModel (예 : null 및 String.Empty) 이러한 제거 할 수 있지만 AutoCompleteBox 원래 SearchText 속성을 유지하고 사용자 입력 텍스트를 다시 설정합니다. 최종 선택 사항이지만 드롭 다운을 표시하는 원래 입력 된 문자). 나는이 질문을 여러 포럼에 게시했습니다. 나는 그것을 분류 할 수 없었습니다. – EzaBlade

+0

속성 안에서 OnPropertyChanged를 호출하고 Binding을 TwoWay로 설정하십시오. 내 예제에서는 이러한 조건을 구현하므로 문제가 해결됩니다. 그렇지 않은 경우 문제에 대한 자세한 설명과 함께 새로운 질문을 할 수 있습니다. – vorrtex

+0

나는 (자기 자신에 기인 한) 내 문제를 해결했다. – EzaBlade