1

Silverlight에서 INotifyDataErrorInfo 구현을 사용하여 간단한 유효성 검사를 사용하고 있습니다.유효성 검사를 위해 INotifyDataErrorInfo를 사용할 때 컨트롤에 다시 집중하십시오.

제출할 때 모든 오류를 표시하기 위해 모든 속성의 유효성을 검사하고 있습니다.

유효성 검사가 발생하면 유효성 검사 오류가있는 첫 번째 컨트롤로 포커스를 되돌려 야합니다.

우리는 이것을 할 방법이 있습니까? 어떤 제안?

답변

0

더 늦어서는 안됩니다.

이 동작을 구현했습니다.

먼저 ViewModel ErrorsChangedPropertyChanged 메서드를 구독해야합니다. 내 생성자에서이 일을하고있다 :

/// <summary> 
    /// If model errors has changed and model still have errors set flag to true, 
    /// if we dont have errors - set flag to false. 
    /// </summary> 
    /// <param name="sender">Ignored.</param> 
    /// <param name="e">Ignored.</param> 
    private void _ViewModelErrorsChanged(object sender, DataErrorsChangedEventArgs e) 
    { 
     if ((this.DataContext as INotifyDataErrorInfo).HasErrors) 
      _hasErrorsRecentlyChanged = true; 
     else 
      _hasErrorsRecentlyChanged = false; 
    } 

    /// <summary> 
    /// Iterate over view model visual childrens. 
    /// </summary> 
    /// <param name="sender">Ignored.</param> 
    /// <param name="e">Ignored.</param> 
    private void _ViewModelPropertyChanged(object sender, PropertyChangedEventArgs e) 
    { 
     if ((this.DataContext as INotifyDataErrorInfo).HasErrors) 
      _LoopThroughControls(this); 
    } 

을 그리고 마지막 방법 추가 :

/// <summary> 
    /// Initializes new instance of the View class. 
    /// </summary> 
    public View(ViewModel viewModel) 
    { 
     if (viewModel == null) 
      throw new ArgumentNullException("viewModel"); 

     // Initialize the control 
     InitializeComponent(); // exception 

     // Set view model to data context. 
     DataContext = viewModel; 

     viewModel.PropertyChanged += new PropertyChangedEventHandler(_ViewModelPropertyChanged); 
     viewModel.ErrorsChanged += new EventHandler<DataErrorsChangedEventArgs>(_ViewModelErrorsChanged); 
    } 

그런 다음이 이벤트에 대한 핸들러를 쓰기

/// <summary> 
    /// If we have error and we haven't already set focus - set focus to first control with error. 
    /// </summary> 
    /// <remarks>Recursive.</remarks> 
    /// <param name="parent">Parent element.</param> 
    private void _LoopThroughControls(UIElement parent) 
    { 
     // Check that we have error and we haven't already set focus 
     if (!_hasErrorsRecentlyChanged) 
      return; 

     int count = VisualTreeHelper.GetChildrenCount(parent); 

     // VisualTreeHelper.GetChildrenCount for TabControl will always return 0, so we need to 
     // do this branch of code. 
     if (parent.GetType().Equals(typeof(TabControl))) 
     { 
      TabControl tabContainer = ((TabControl)parent); 
      foreach (TabItem tabItem in tabContainer.Items) 
      { 
       if (tabItem.Content == null) 
        continue; 

       _LoopThroughControls(tabItem.Content as UIElement); 
      } 
     } 

     // If element has childs. 
     if (count > 0) 
     { 
      for (int i = 0; i < count; i++) 
      { 
       UIElement child = (UIElement)VisualTreeHelper.GetChild(parent, i); 

       if (child is System.Windows.Controls.Control) 
       { 
        var control = (System.Windows.Controls.Control)child; 

        // If control have error - we found first control, set focus to it and 
        // set flag to false. 
        if ((bool)control.GetValue(Validation.HasErrorProperty)) 
        { 
         _hasErrorsRecentlyChanged = false; 
         control.Focus(); 
         return; 
        } 
       } 

       _LoopThroughControls(child); 
      } 
     } 
    } 
관련 문제