2011-06-06 7 views
9

SelamlarSilverlight'ta, bir hataya sahip olan bir modele ciltlenmiş ilk alanı nasıl bulabilirim, böylece odaklanabilir miyim?

INotifyDataErrorInfo uygulayan ve kaydet düğmesini tıklattığınızda doğrulama yapan bir model nesnesine bağlı bir Silverlight formum var. Modeldeki özelliklerin bir kısmı geçersiz olursa, Silverlight otomatik olarak ciltlenmiş giriş alanını vurgulayacaktır.

Odağı ilk geçersiz alana ayarlamanın bir yolu var mı?

GÜNCELLEME: Bir giriş alanının geçersiz görüntüleme durumunda olup olmadığını görmenin bir yolu var mı? Bunu algılayabilirsem, alanlarımda dolaşabilir ve odağı manuel olarak ayarlayabilirim.

sayesinde Matta

cevap

1

Ben bu davranışı uyguladık yardımcı olacaktır. İlk önce ViewModel ErrorsChanged ve PropertyChanged yöntemlerine abone olmanız gerekir. Benim yapıcı içinde yapıyorum:

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

O zaman bu olaylara işleyici yazın: Sadece bunu sona erdi

/// <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); 
      } 
     } 
    } 
4

Modeliniz kaldırdı tüm doğrulama hatalarını görüntülemek için görünümünde bir ValidationSummary kullanabilirsiniz. ValidationSummary'da bir hatayı tıklattığınızda, doğrulama hatasına neden olan kontrol odaklanacaktır.

ValidationSummary'ın bir örneği, Silverlight Toolkit'in samples adresinde bulunabilir.

Şimdiye kadar herhangi bir uygulamada ValidationSummary kullanmak etmedin, bu yüzden size kullanım veya "nasıl kullanmak" hakkında herhangi bir bilgi sağlayamaz, ama belki this sen

+0

:

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

Ve nihayet yöntemini ekleyin. İdeal değil ama şimdilik yeterince iyi. – Matthew