Note that there are some explanatory texts on larger screens.

plurals
  1. PO
    primarykey
    data
    text
    <p>I've implemented this behavior. First you need to subscribe to your ViewModel <code>ErrorsChanged</code> and <code>PropertyChanged</code> methods. I am doing this in my constructor:</p> <pre><code> /// &lt;summary&gt; /// Initializes new instance of the View class. /// &lt;/summary&gt; 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&lt;DataErrorsChangedEventArgs&gt;(_ViewModelErrorsChanged); } </code></pre> <p>Then write handlers for this events:</p> <pre><code> /// &lt;summary&gt; /// If model errors has changed and model still have errors set flag to true, /// if we dont have errors - set flag to false. /// &lt;/summary&gt; /// &lt;param name="sender"&gt;Ignored.&lt;/param&gt; /// &lt;param name="e"&gt;Ignored.&lt;/param&gt; private void _ViewModelErrorsChanged(object sender, DataErrorsChangedEventArgs e) { if ((this.DataContext as INotifyDataErrorInfo).HasErrors) _hasErrorsRecentlyChanged = true; else _hasErrorsRecentlyChanged = false; } /// &lt;summary&gt; /// Iterate over view model visual childrens. /// &lt;/summary&gt; /// &lt;param name="sender"&gt;Ignored.&lt;/param&gt; /// &lt;param name="e"&gt;Ignored.&lt;/param&gt; private void _ViewModelPropertyChanged(object sender, PropertyChangedEventArgs e) { if ((this.DataContext as INotifyDataErrorInfo).HasErrors) _LoopThroughControls(this); } </code></pre> <p>And finally add method:</p> <pre><code> /// &lt;summary&gt; /// If we have error and we haven't already set focus - set focus to first control with error. /// &lt;/summary&gt; /// &lt;remarks&gt;Recursive.&lt;/remarks&gt; /// &lt;param name="parent"&gt;Parent element.&lt;/param&gt; 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 &gt; 0) { for (int i = 0; i &lt; 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); } } } </code></pre>
    singulars
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    plurals
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. VO
      singulars
      1. This table or related slice is empty.
    2. VO
      singulars
      1. This table or related slice is empty.
    1. This table or related slice is empty.
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload